aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/draw/draw.odin316
-rw-r--r--src/draw/framebuffer.odin94
-rw-r--r--src/draw/sprite.odin44
-rw-r--r--src/input.odin52
-rw-r--r--src/main.odin131
-rw-r--r--src/phys/body.odin3
-rw-r--r--src/phys/world.odin77
-rw-r--r--src/platform.odin6
-rw-r--r--src/player.odin36
9 files changed, 198 insertions, 561 deletions
diff --git a/src/draw/draw.odin b/src/draw/draw.odin
index 6c013de..6761b36 100644
--- a/src/draw/draw.odin
+++ b/src/draw/draw.odin
@@ -1,12 +1,9 @@
package draw
-import "core:math/linalg"
import "core:math"
+import "core:c"
-import sg "shared:sokol/gfx"
-import sapp "shared:sokol/app"
-import sdtxt "shared:sokol/debugtext"
-import sglue "shared:sokol/glue"
+import rl "vendor:raylib"
Vec2 :: [2]f32
Vec3 :: [3]f32
@@ -23,238 +20,69 @@ Color :: [4]f32
SCREEN_WIDTH :: 480
SCREEN_HEIGHT :: 360
-Renderer :: struct {
- screen: Framebuffer,
-
- window_pass: struct {
- pass_action: sg.Pass_Action,
- pipe: sg.Pipeline,
- },
-
- view: sg.View,
- sampler: sg.Sampler,
-
- white_1x1: sg.Image,
-
- projection: Mat4,
- current_batch: Batch,
-
+renderer: struct {
+ screen: rl.RenderTexture2D,
tint: Color,
}
-Vertex :: struct {
- pos: Vec2,
- uv: Vec2,
- color: Color,
-}
-
-Batch :: struct {
- img: sg.Image,
- vertices: [dynamic]Vertex,
-}
-
-init :: proc(r: ^Renderer) {
- r.window_pass.pipe = sg.make_pipeline({
- shader = sg.make_shader(default_shader_desc(sg.query_backend())),
- layout = {
- attrs = {
- ATTR_default_vposition = {format = .FLOAT2},
- ATTR_default_vuv = {format = .FLOAT2},
- ATTR_default_vcolor = {format = .FLOAT4},
- },
- },
- })
-
- r.window_pass.pass_action = {
- colors = {
- 0 = {load_action = .CLEAR, clear_value = {0, 0, 0, 1}},
- },
+@(private)
+color_to_rl :: proc(col: Color) -> rl.Color {
+ return rl.Color{
+ u8(col.r * 255),
+ u8(col.g * 255),
+ u8(col.b * 255),
+ u8(col.a * 255),
}
-
- white := [?]u8{255, 255, 255, 255}
-
- r.white_1x1 = sg.make_image({
- width = 1,
- height = 1,
- data = {
- mip_levels = {
- 0 = {ptr=&white, size=size_of(white)},
- },
- },
- })
-
- init_framebuffer(
- &r.screen,
- SCREEN_WIDTH, SCREEN_HEIGHT,
- Color{0.2, 0.2, 0.2, 1.0},
- )
-
- r.view = sg.alloc_view()
- r.sampler = sg.make_sampler({})
-
- r.tint = {1, 1, 1, 1}
-
- sdtxt.set_context(sdtxt.make_context({
- color_format = .RGBA8,
- depth_format = .NONE,
- sample_count = 1,
- }))
-}
-
-deinit :: proc(r: ^Renderer) {
- delete_batch(&r.current_batch)
-
- sg.destroy_pipeline(r.window_pass.pipe)
-
- sg.destroy_view(r.view)
- sg.destroy_sampler(r.sampler)
-
- destroy_framebuffer(&r.screen)
}
-new_frame :: proc(r: ^Renderer) {
- framebuffer_draw_start(r.screen)
- r.projection = linalg.matrix_ortho3d(
- 0, f32(SCREEN_WIDTH),
- f32(SCREEN_HEIGHT), 0,
- 0.0, 1.0,
- )
+init :: proc() {
+ renderer.screen = rl.LoadRenderTexture(SCREEN_WIDTH, SCREEN_HEIGHT)
+ renderer.tint = Color{1, 1, 1, 1}
}
-end_frame :: proc(r: ^Renderer) {
- flush_current_batch(r)
- clear(&r.current_batch.vertices)
-
- sdtxt.draw()
-
- framebuffer_draw_end(r.screen)
-
- r.projection = linalg.matrix_ortho3d(
- 0, f32(sapp.width()),
- 0, f32(sapp.height()),
- 0.0, 1.0,
- )
-
- sg.begin_pass({action=r.window_pass.pass_action, swapchain=sglue.swapchain()})
- sg.apply_pipeline(r.window_pass.pipe)
-
- scale := math.min(
- f32(sapp.height()) / f32(SCREEN_HEIGHT) ,
- f32(sapp.width()) / f32(SCREEN_WIDTH),
- )
- screen_start := Vec2{
- (f32(sapp.width()) - (SCREEN_WIDTH * scale)) / 2,
- (f32(sapp.height()) - (SCREEN_HEIGHT * scale)) / 2,
- }
-
- texture(
- r,
- r.screen.img,
- screen_start,
- scale = Vec2{scale, scale},
- )
-
- flush_current_batch(r)
- clear(&r.current_batch.vertices)
-
- sg.end_pass()
-
- sg.commit()
+deinit :: proc() {
+ rl.UnloadRenderTexture(renderer.screen)
}
-@(private)
-delete_batch :: proc(batch: ^Batch) {
- delete(batch.vertices)
+new_frame :: proc() {
+ rl.BeginTextureMode(renderer.screen)
+ rl.ClearBackground(color_to_rl(Color{0.2, 0.2, 0.2, 1}))
}
-flush_current_batch :: proc(r: ^Renderer) {
- batch := r.current_batch
-
- if len(batch.vertices) == 0 {
- return
- }
-
- buffer := sg.make_buffer({
- data = {
- ptr = &r.current_batch.vertices[0],
- size = size_of(Vertex) * len(r.current_batch.vertices),
- },
- })
-
- sg.init_view(r.view, {
- texture = {
- image = r.current_batch.img,
- },
- })
-
- binds: sg.Bindings
-
- binds.vertex_buffers[0] = buffer
- binds.views[VIEW_tex] = r.view
- binds.samplers[SMP_tex_samp] = r.sampler
+end_frame :: proc() {
+ rl.EndTextureMode()
- uniforms := Default_Vs_Params {
- projection = transmute([16]f32)r.projection,
- }
-
- sg.apply_bindings(binds)
- sg.apply_uniforms(UB_default_vs_params, {ptr=&uniforms, size=size_of(uniforms)})
-
- sg.draw(0, len(r.current_batch.vertices), 1)
-
- sg.uninit_view(r.view)
-
- sg.destroy_buffer(buffer)
-}
+ rl.BeginDrawing()
+ {
+ rl.ClearBackground(color_to_rl(Color{0, 0, 0, 1}))
+ scale := math.min(
+ f32(rl.GetScreenWidth()) / f32(SCREEN_WIDTH),
+ f32(rl.GetScreenHeight()) / f32(SCREEN_HEIGHT),
+ )
+ screen_start := Vec2{
+ (f32(rl.GetScreenWidth()) - (SCREEN_WIDTH * scale)) / 2,
+ (f32(rl.GetScreenHeight()) - (SCREEN_HEIGHT * scale)) / 2,
+ }
-@(private)
-new_batch :: proc(batch: ^Batch, img: sg.Image) {
- clear(&batch.vertices)
- batch.img = img
-}
-
-request_batch :: proc(r: ^Renderer, img: sg.Image) -> ^Batch {
- if len(r.current_batch.vertices) == 0 {
- new_batch(&r.current_batch, img)
- } else if img != r.current_batch.img {
- flush_current_batch(r)
- new_batch(&r.current_batch, img)
+ texture_full(
+ renderer.screen.texture,
+ screen_start,
+ scale = Vec2{scale, scale},
+ )
}
-
- return &r.current_batch
-}
-
-@(private)
-batch_vertices :: proc(
- b: ^Batch,
- vertices: []Vertex,
-) {
- append(&b.vertices, ..vertices)
+ rl.EndDrawing()
}
rect :: proc(
- r: ^Renderer,
rect: Rect,
- color := Color{1, 1, 1, 1},
) {
assert(rect.size.x > 0 && rect.size.y > 0)
- batch := request_batch(r, r.white_1x1)
-
- start := rect.start
- end := rect.start + rect.size
-
- vertices := [?]Vertex{
- {start, {0, 0}, r.tint},
- {{end.x, start.y}, {1, 0}, r.tint},
- {{start.x, end.y}, {0, 1}, r.tint},
-
- {{end.x, start.y}, {1, 0}, r.tint},
- {{start.x, end.y}, {0, 1}, r.tint},
- {end, {1, 1}, r.tint},
- }
-
- batch_vertices(batch, vertices[:])
+ rl.DrawRectangle(
+ c.int(rect.start.x), c.int(rect.start.y),
+ c.int(rect.size.x), c.int(rect.size.y),
+ color_to_rl(renderer.tint),
+ )
}
texture :: proc{
@@ -263,52 +91,42 @@ texture :: proc{
}
texture_quad :: proc(
- r: ^Renderer,
- img: sg.Image,
+ img: rl.Texture2D,
quad: Rect,
- pos: Vec2,
+ position: Vec2,
offset := Vec2{0, 0},
+ rotation: f32 = 0,
scale := Vec2{1, 1},
) {
- assert(quad.size.x > 0 && quad.size.y > 0)
+ // assert(quad.size.x > 0 && quad.size.y > 0)
- batch := request_batch(r, img)
-
- top_left := pos + offset * scale
- bot_rght := top_left + quad.size * scale
+ quad := quad
+ quad.size *= scale
- size := Vec2{
- f32(sg.query_image_width(img)),
- f32(sg.query_image_height(img)),
- }
-
- uv_start := quad.start / size
- uv_end := (quad.start + quad.size) / size
-
- // |/|
- vertices := [?]Vertex{
- {top_left, uv_start, r.tint},
- {{bot_rght.x, top_left.y}, {uv_end.x, uv_start.y}, r.tint},
- {{top_left.x, bot_rght.y}, {uv_start.x, uv_end.y }, r.tint},
-
- {{bot_rght.x, top_left.y}, {uv_end.x, uv_start.y}, r.tint},
- {{top_left.x, bot_rght.y}, {uv_start.x, uv_end.y }, r.tint},
- {bot_rght, uv_end, r.tint},
- }
-
- batch_vertices(batch, vertices[:])
+ rl.DrawTexturePro(
+ img,
+ transmute(rl.Rectangle)quad,
+ rl.Rectangle{
+ position.x, position.y,
+ quad.size.x * scale.x, quad.size.y * scale.y,
+ },
+ offset,
+ rotation,
+ color_to_rl(renderer.tint),
+ )
}
texture_full :: proc(
- r: ^Renderer,
- img: sg.Image,
- pos: Vec2,
+ img: rl.Texture2D,
+ position: Vec2,
offset := Vec2{0, 0},
+ rotation: f32 = 0,
scale := Vec2{1, 1},
) {
size := Vec2{
- f32(sg.query_image_width(img)),
- f32(sg.query_image_height(img)),
+ f32(img.width),
+ -f32(img.height),
}
- texture_quad(r, img, Rect{Vec2{0, 0}, size}, pos, offset, scale)
+
+ texture_quad(img, Rect{Vec2{0, 0}, size}, position, offset, rotation, scale)
}
diff --git a/src/draw/framebuffer.odin b/src/draw/framebuffer.odin
deleted file mode 100644
index cd7848b..0000000
--- a/src/draw/framebuffer.odin
+++ /dev/null
@@ -1,94 +0,0 @@
-package draw
-
-import sg "shared:sokol/gfx"
-
-Framebuffer :: struct {
- img: sg.Image,
- view: sg.View,
- pipe: sg.Pipeline,
- pass: sg.Pass,
-}
-
-init_framebuffer :: proc(
- fb: ^Framebuffer,
- width: i32,
- height: i32,
- clear_color := Color{0, 0, 0, 0},
-) {
- fb.pipe = sg.make_pipeline({
- shader = sg.make_shader(default_shader_desc(sg.query_backend())),
- layout = {
- attrs = {
- ATTR_default_vposition = {format = .FLOAT2},
- ATTR_default_vuv = {format = .FLOAT2},
- ATTR_default_vcolor = {format = .FLOAT4},
- },
- },
- depth = {
- pixel_format = .NONE,
- },
- sample_count = 1,
- colors = {
- 0 = {
- pixel_format = .RGBA8,
- blend = {
- enabled = true,
- src_factor_rgb = .SRC_ALPHA,
- dst_factor_rgb = .ONE_MINUS_SRC_ALPHA,
- src_factor_alpha = .ONE,
- dst_factor_alpha = .ZERO,
- },
- },
- },
- })
-
- fb.img = sg.make_image({
- usage = {
- color_attachment = true,
- },
-
- width = width,
- height = height,
-
- pixel_format = .RGBA8,
- sample_count = 1,
- })
-
- fb.view = sg.make_view({
- texture = {
- image = fb.img,
- },
- })
-
- fb.pass = {
- attachments = {
- colors = {
- 0 = sg.make_view({
- color_attachment = {
- image = fb.img,
- },
- }),
- },
- },
- action = {
- colors = {
- 0 = {load_action = .CLEAR, clear_value = transmute(sg.Color)clear_color},
- },
- },
- }
-}
-
-destroy_framebuffer :: proc(fb: ^Framebuffer) {
- sg.destroy_pipeline(fb.pipe)
- sg.destroy_view(fb.view)
- sg.destroy_image(fb.img)
-}
-
-framebuffer_draw_start :: proc(fb: Framebuffer) {
- sg.begin_pass(fb.pass)
- sg.apply_pipeline(fb.pipe)
-}
-
-framebuffer_draw_end :: proc(fb: Framebuffer) {
- sg.end_pass()
-}
diff --git a/src/draw/sprite.odin b/src/draw/sprite.odin
index 59d1c32..a6a109b 100644
--- a/src/draw/sprite.odin
+++ b/src/draw/sprite.odin
@@ -1,13 +1,14 @@
package draw
import "core:log"
-import "core:image"
-import "core:image/qoi"
+// import "core:image"
+import "core:mem"
+// import "core:image/qoi"
-import sg "shared:sokol/gfx"
+import rl "vendor:raylib"
Sprite :: struct {
- image: sg.Image,
+ image: rl.Texture2D,
anim: Animation,
active_anim: u32,
frame_time: f32,
@@ -18,6 +19,7 @@ Sprite :: struct {
pos: Vec2,
offset: Vec2,
+ rotation: f32,
scale: Vec2,
}
@@ -26,26 +28,15 @@ init_sprite :: proc(
path: string,
anim: Animation = {},
) -> bool {
- img, img_err := qoi.load_from_file(path)
- if img_err != nil {
- log.error("could not load image")
- return false
- }
- defer image.destroy(img)
+ byte_path := make([]u8, len(path) + 1, context.temp_allocator)
+ copy(byte_path, path)
+ byte_path[len(path)] = 0
- sprite.image = sg.make_image({
- width = i32(img.width),
- height = i32(img.height),
- data = {
- mip_levels = {
- 0 = {ptr=&img.pixels.buf[0], size=len(img.pixels.buf)},
- },
- },
- })
+ sprite.image = rl.LoadTexture(transmute(cstring)&byte_path[0])
sprite.anim = anim
- sprite.width = i32(img.width / len(sprite.anim.frames))
- sprite.height = i32(img.height)
+ sprite.width = i32(int(sprite.image.width) / len(sprite.anim.frames))
+ sprite.height = i32(sprite.image.height)
sprite.scale = Vec2{1, 1}
@@ -53,12 +44,16 @@ init_sprite :: proc(
"loaded sprite '%v' %vx%v (%vx%v)",
path,
sprite.width, sprite.height,
- img.width, img.height,
+ sprite.image.width, sprite.image.height,
)
return true
}
+destroy_sprite :: proc(sprite: Sprite) {
+ rl.UnloadTexture(sprite.image)
+}
+
set_sprite_active_tag :: proc(sprite: ^Sprite, tag_name: string) {
sprite.active_anim = sprite.anim.frame_tags_indices[tag_name]
}
@@ -84,13 +79,11 @@ update_sprite :: proc(sprite: ^Sprite, dt: f32) {
}
sprite :: proc(
- r: ^Renderer,
sprite: Sprite,
) {
frame := sprite.anim.frames[sprite.current_frame]
- texture(
- r,
+ texture_quad(
sprite.image,
Rect {
Vec2{f32(frame.rect.x), f32(frame.rect.y)},
@@ -98,6 +91,7 @@ sprite :: proc(
},
sprite.pos,
sprite.offset,
+ sprite.rotation,
sprite.scale,
)
}
diff --git a/src/input.odin b/src/input.odin
index 6c02349..de2af7e 100644
--- a/src/input.odin
+++ b/src/input.odin
@@ -1,10 +1,10 @@
package demonchime
-import sapp "shared:sokol/app"
+import rl "vendor:raylib"
KeybindInput :: union {
- sapp.Keycode,
- sapp.Mousebutton,
+ rl.KeyboardKey,
+ rl.MouseButton,
}
Keybind :: struct {
@@ -13,44 +13,36 @@ Keybind :: struct {
just_pressed: bool,
}
-Input :: struct {
+actions: struct {
move_left: Keybind,
move_right: Keybind,
jump: Keybind,
-
- key_down: [sapp.MAX_KEYCODES]bool,
- key_just_down: [sapp.MAX_KEYCODES]bool,
- mouse_down: [sapp.MAX_MOUSEBUTTONS]bool,
- mouse_just_down: [sapp.MAX_MOUSEBUTTONS]bool,
}
-init_keybinds :: proc(input: ^Input) {
- input.move_left.input = sapp.Keycode.A
- input.move_right.input = sapp.Keycode.D
- input.jump.input = sapp.Keycode.SPACE
+init_keybinds :: proc() {
+ actions.move_left.input = .A
+ actions.move_right.input = .D
+ actions.jump.input = .SPACE
}
-input_event :: proc(event: ^sapp.Event, input: ^Input) {
- #partial switch event.type {
- case .KEY_DOWN:
- input.key_down[event.key_code] = true
- input.key_just_down[event.key_code] = true
- case .KEY_UP:
- input.key_down[event.key_code] = false
- case .MOUSE_DOWN:
- input.mouse_down[event.key_code] = true
- input.mouse_just_down[event.key_code] = true
- case .MOUSE_UP:
- input.mouse_down[event.key_code] = false
+is_keybind_down :: proc(keybind: Keybind) -> bool {
+ switch val in keybind.input {
+ case rl.KeyboardKey:
+ return rl.IsKeyDown(val)
+ case rl.MouseButton:
+ return rl.IsMouseButtonDown(val)
}
+
+ assert(false)
+ return false
}
-is_keybind_down :: proc(input: Input, keybind: Keybind) -> bool {
+is_keybind_just_down :: proc(keybind: Keybind) -> bool {
switch val in keybind.input {
- case sapp.Keycode:
- return input.key_down[val]
- case sapp.Mousebutton:
- return input.mouse_down[val]
+ case rl.KeyboardKey:
+ return rl.IsKeyPressed(val)
+ case rl.MouseButton:
+ return rl.IsMouseButtonPressed(val)
}
assert(false)
diff --git a/src/main.odin b/src/main.odin
index 2ca3e7f..9a6c09a 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -7,13 +7,9 @@ package demonchime
import "base:runtime"
import "core:log"
+import "core:fmt"
-import sg "shared:sokol/gfx"
-import sapp "shared:sokol/app"
-import sglue "shared:sokol/glue"
-import stime "shared:sokol/time"
-import slog "shared:sokol/log"
-import sdtxt "shared:sokol/debugtext"
+import rl "vendor:raylib"
import "draw"
import "phys"
@@ -27,47 +23,13 @@ Rect :: struct {
state: struct {
player: Player,
-
platform_list: Entity_List(Platform),
-
- renderer: draw.Renderer,
- physics_world: phys.World,
-
- input: Input,
-
- fps: f32,
- last_fps: f32,
- frames_rendered: int,
}
-logger: log.Logger
-
-default_context :: proc "contextless" () -> runtime.Context {
- ctx := runtime.default_context()
- ctx.logger = logger
- return ctx
-}
-
-init :: proc "c" () {
- context = default_context()
-
- stime.setup()
-
- sg.setup({
- environment = sglue.environment(),
- logger = {func=slog.func},
- })
-
- sdtxt.setup({
- fonts = {
- 0 = sdtxt.font_kc853(),
- },
- logger = {func=slog.func},
- })
+init :: proc() {
+ init_keybinds()
- init_keybinds(&state.input)
-
- draw.init(&state.renderer)
+ draw.init()
init_player(&state.player)
@@ -89,17 +51,14 @@ init :: proc "c" () {
start = {160, 320},
size = {20, 20}
})
-
make_platform(Rect{
start = {240, 280},
size = {40, 20}
})
-
make_platform(Rect{
start = {260, 260},
size = {20, 20}
})
-
make_platform(Rect{
start = {300, 220},
size = {40, 20}
@@ -126,74 +85,44 @@ init :: proc "c" () {
})
}
-frame :: proc "c" () {
- context = default_context()
-
- update_player(&state.player, f32(sapp.frame_duration()))
-
- // sdtxt.canvas(f32(sapp.width()), f32(sapp.height()))
- sdtxt.canvas(draw.SCREEN_WIDTH, draw.SCREEN_HEIGHT)
- sdtxt.origin(0.1, 0.1)
- sdtxt.home()
- sdtxt.font(0)
+frame :: proc() {
+ update_player(&state.player, rl.GetFrameTime())
- stats := sg.query_frame_stats()
- sdtxt.printf("FPS: %f\n", state.fps)
- sdtxt.printf("Draw calls: %d\n", stats.num_draw)
+ draw.new_frame()
- draw.new_frame(&state.renderer)
-
- draw_player(state.player)
+ fps_text := fmt.caprintf(
+ "FPS: %v", rl.GetFPS(),
+ allocator = context.temp_allocator,
+ )
+ rl.DrawText(fps_text, 5, 5, 8, rl.GREEN)
draw_platforms()
+ draw_player(state.player)
- draw.end_frame(&state.renderer)
-
- free_all(context.temp_allocator)
-
- state.frames_rendered += 1
- now := f32(stime.sec(stime.now()))
- if now - state.last_fps > 1 {
- state.fps = f32(state.frames_rendered) / (now - state.last_fps)
- state.last_fps = now
- state.frames_rendered = 0
- }
-}
-
-event :: proc "c" (event: ^sapp.Event) {
- context = default_context()
-
- if event.type == .KEY_DOWN && event.key_code == .ESCAPE {
- sapp.quit()
- }
-
- input_event(event, &state.input)
+ draw.end_frame()
}
-cleanup :: proc "c" () {
- context = default_context()
- sg.shutdown()
- sdtxt.shutdown()
-
+cleanup :: proc() {
delete_entity_list(state.platform_list)
}
main :: proc() {
- logger = log.create_console_logger()
+ logger := log.create_console_logger()
context.logger = logger
+ defer log.destroy_console_logger(logger)
- sapp.run({
- init_cb = init,
- frame_cb = frame,
- event_cb = event,
- cleanup_cb = cleanup,
- width = 800,
- height = 600,
- window_title = "Demonchime",
- icon = {sokol_default = true},
- logger = {func=slog.func},
- })
+ rl.InitWindow(480 * 2, 360 * 2, "Demonchime")
+
+ rl.SetWindowState({.WINDOW_RESIZABLE})
+
+ init()
+
+ for !rl.WindowShouldClose() {
+ frame()
+
+ free_all(context.temp_allocator)
+ }
- log.destroy_console_logger(logger)
+ cleanup()
}
diff --git a/src/phys/body.odin b/src/phys/body.odin
index fcae697..0256dee 100644
--- a/src/phys/body.odin
+++ b/src/phys/body.odin
@@ -37,7 +37,6 @@ Body :: struct {
}
make_body :: proc(
- w: ^World,
rect: Rect,
layers := bit_set[Layer; u16]{.DEFAULT},
mask := bit_set[Layer; u16]{.DEFAULT},
@@ -48,7 +47,7 @@ make_body :: proc(
mask = mask,
active = true,
}
- return add_body(w, b)
+ return add_body(b)
}
aabb_hori :: proc(a: Rect, b: Rect) -> bool {
diff --git a/src/phys/world.odin b/src/phys/world.odin
index eac3d5c..3154a0b 100644
--- a/src/phys/world.odin
+++ b/src/phys/world.odin
@@ -3,22 +3,22 @@ package phys
import "core:log"
import "core:math"
-import sapp "shared:sokol/app"
+import rl "vendor:raylib"
BIN_COUNT :: 2056
BIN_SIZE :: 64
Body_Handle :: u32
-World :: struct {
+world: struct {
handles: [dynamic]u32,
unused_handles: [dynamic]Body_Handle,
bodies: [dynamic]Body,
bins: [BIN_COUNT][dynamic]Body_Handle,
}
-destroy_world :: proc(w: World) {
- for bin in w.bins {
+destroy_world :: proc() {
+ for bin in world.bins {
delete(bin)
}
}
@@ -37,7 +37,6 @@ world_to_bin :: proc(point: Vec2) -> (i32, i32) {
@(private="file")
get_surrounding_bins :: proc(
- w: ^World,
pos: Vec2,
allocator := context.temp_allocator,
) -> []^[dynamic]Body_Handle {
@@ -50,7 +49,7 @@ get_surrounding_bins :: proc(
for offset_x in -1..=1 {
for offset_y in -1..=1 {
bin_idx := hash_bin(center_x + i32(offset_x), center_y + i32(offset_y))
- bin := &w.bins[bin_idx % BIN_COUNT]
+ bin := &world.bins[bin_idx % BIN_COUNT]
neighbors[idx] = bin
idx += 1
}
@@ -60,79 +59,79 @@ get_surrounding_bins :: proc(
}
@(private="file")
-find_bin :: proc(w: ^World, b: Body) -> ^[dynamic]Body_Handle {
+find_bin :: proc(b: Body) -> ^[dynamic]Body_Handle {
bin_x, bin_y := world_to_bin(b.pos + b.rect.start)
- return &w.bins[hash_bin(bin_x, bin_y) % BIN_COUNT]
+ return &world.bins[hash_bin(bin_x, bin_y) % BIN_COUNT]
}
@(private="file")
-add_to_bins :: proc(w: ^World, b: Body) {
- bin := find_bin(w, b)
+add_to_bins :: proc(b: Body) {
+ bin := find_bin(b)
idx := i32(len(bin))
append(bin, b.handle)
- w.bodies[bin[idx]].bin_idx = idx
+ world.bodies[bin[idx]].bin_idx = idx
}
@(private="file")
-remove_from_bins :: proc(w: ^World, b: Body) {
- bin := find_bin(w, b)
+remove_from_bins :: proc(b: Body) {
+ bin := find_bin(b)
assert(bin[b.bin_idx] == b.handle)
last := pop(bin)
if last != b.handle {
bin[b.bin_idx] = last
- w.bodies[last].bin_idx = b.bin_idx
+ world.bodies[last].bin_idx = b.bin_idx
}
}
-get_body :: proc(w: World, h: Body_Handle) -> ^Body {
- return &w.bodies[w.handles[h]]
+get_body :: proc(h: Body_Handle) -> ^Body {
+ return &world.bodies[world.handles[h]]
}
-add_body :: proc(w: ^World, b: Body) -> (Body_Handle, ^Body) {
+add_body :: proc(b: Body) -> (Body_Handle, ^Body) {
handle: Body_Handle
if b.rect.size.x > BIN_SIZE || b.rect.size.y > BIN_SIZE {
log.warnf("Body size is too big (%vx%v)", b.rect.size.x, b.rect.size.y)
}
- if len(w.unused_handles) > 0 {
- handle = pop(&w.unused_handles)
+ if len(world.unused_handles) > 0 {
+ handle = pop(&world.unused_handles)
} else {
- handle = cast(Body_Handle)len(w.handles)
- append(&w.handles, 0)
+ handle = cast(Body_Handle)len(world.handles)
+ append(&world.handles, 0)
}
- w.handles[handle] = u32(len(w.bodies))
- append(&w.bodies, b)
+ world.handles[handle] = u32(len(world.bodies))
+ append(&world.bodies, b)
- body := &w.bodies[w.handles[handle]]
+ body := &world.bodies[world.handles[handle]]
body.handle = handle
- add_to_bins(w, body^)
+ add_to_bins(body^)
return handle, body
}
-remove_body :: proc(w: ^World, h: Body_Handle) {
- b := get_body(w^, h)
+remove_body :: proc(h: Body_Handle) {
+ b := get_body(h)
- remove_from_bins(w, b^)
+ remove_from_bins(b^)
- last := pop(&w.bodies)
+ last := pop(&world.bodies)
if last.handle != h {
- w.bodies[h] = last
- w.handles[last.handle] = w.handles[h]
+ world.bodies[h] = last
+ world.handles[last.handle] = world.handles[h]
}
- append(&w.unused_handles, b.handle)
+ append(&world.unused_handles, b.handle)
}
-update_body :: proc(w: ^World, h: Body_Handle) {
- dt := f32(sapp.frame_duration())
+update_body :: proc(h: Body_Handle) {
+ dt := rl.GetFrameTime()
- b := get_body(w^, h)
+ b := get_body(h)
res_pos := b.pos + b.vel * dt
@@ -142,7 +141,7 @@ update_body :: proc(w: ^World, h: Body_Handle) {
res_rect := b.rect
res_rect.start += res_pos
- bin_list := get_surrounding_bins(w, res_rect.start)
+ bin_list := get_surrounding_bins(res_rect.start)
b.collisions = {}
@@ -156,7 +155,7 @@ update_body :: proc(w: ^World, h: Body_Handle) {
continue
}
- c := get_body(w^, c_h)
+ c := get_body(c_h)
c_rect := c.rect
c_rect.start += c.pos
@@ -198,8 +197,8 @@ update_body :: proc(w: ^World, h: Body_Handle) {
res_bin := hash_bin(world_to_bin(res_pos + b.rect.start))
if prev_bin != res_bin {
- remove_from_bins(w, b^)
- add_to_bins(w, b^)
+ remove_from_bins(b^)
+ add_to_bins(b^)
}
}
diff --git a/src/platform.odin b/src/platform.odin
index 150d96c..674e1a3 100644
--- a/src/platform.odin
+++ b/src/platform.odin
@@ -9,7 +9,7 @@ Platform :: struct {
}
make_platform :: proc(rect: Rect) -> (Entity_Handle, ^Platform) {
- handle, body := phys.make_body(&state.physics_world, transmute(phys.Rect)rect)
+ handle, body := phys.make_body(transmute(phys.Rect)rect)
return make_entity(&state.platform_list, Platform {
body = handle,
})
@@ -18,7 +18,7 @@ make_platform :: proc(rect: Rect) -> (Entity_Handle, ^Platform) {
draw_platforms :: proc() {
iter := iter_entity_list(state.platform_list)
for p in entity_list_iter(&iter) {
- body := phys.get_body(state.physics_world, p.body)
- draw.rect(&state.renderer, cast(draw.Rect)body.rect)
+ body := phys.get_body(p.body)
+ draw.rect(cast(draw.Rect)body.rect)
}
}
diff --git a/src/player.odin b/src/player.odin
index 1fbbb0a..6c34d14 100644
--- a/src/player.odin
+++ b/src/player.odin
@@ -1,9 +1,9 @@
package demonchime
-import "core:fmt"
+import "core:log"
import "core:math"
-import sapp "shared:sokol/app"
+import rl "vendor:raylib"
import "draw"
import "phys"
@@ -25,20 +25,19 @@ Player :: struct {
}
init_player :: proc(p: ^Player) {
- anim_ok := draw.init_anim_data(&p.anim, "res/robot2.json")
+ anim_ok := draw.init_anim_data(&p.anim, "res/player.json")
if !anim_ok {
- fmt.println("coult not load animation")
- sapp.quit()
+ log.warn("could not load animation")
+ rl.CloseWindow()
return
}
handle, body := phys.make_body(
- &state.physics_world,
- phys.Rect{{-8, -17}, {16, 16}},
+ phys.Rect{{8, 17}, {16, 16}},
)
p.body_handle = handle
- body.pos = Vec2{50, 50}
+ body.pos = Vec2{50, 0}
draw.init_sprite(&p.sprite, p.anim.image_path, p.anim)
@@ -49,33 +48,34 @@ init_player :: proc(p: ^Player) {
}
deinit_player :: proc(p: ^Player) {
- phys.remove_body(&state.physics_world, p.body_handle)
+ phys.remove_body(p.body_handle)
+ draw.destroy_sprite(p.sprite)
draw.delete_anim_data(p.anim)
}
update_player :: proc(p: ^Player, dt: f32) {
input: f32
- if is_keybind_down(state.input, state.input.move_left) {
+ if is_keybind_down(actions.move_left) {
input -= 1
}
- if is_keybind_down(state.input, state.input.move_right) {
+ if is_keybind_down(actions.move_right) {
input += 1
}
- if is_keybind_down(state.input, state.input.jump) {
+ if is_keybind_just_down(actions.jump) {
p.jump_buffer = JUMP_BUFFERING
}
if input != 0 {
- draw.set_sprite_active_tag(&p.sprite, "down_run")
+ draw.set_sprite_active_tag(&p.sprite, "run")
p.sprite.scale.x = math.sign(input)
} else {
- draw.set_sprite_active_tag(&p.sprite, "down_idle")
+ draw.set_sprite_active_tag(&p.sprite, "idle")
}
- body := phys.get_body(state.physics_world, p.body_handle)
+ body := phys.get_body(p.body_handle)
if .DOWN in body.collisions {
p.coyote_time = COYOTE_TIME
@@ -88,7 +88,7 @@ update_player :: proc(p: ^Player, dt: f32) {
}
if .DOWN not_in body.collisions \
- && !is_keybind_down(state.input, state.input.jump) \
+ && !is_keybind_down(actions.jump) \
&& body.vel.y < JUMP_RELEASE_CUT {
body.vel.y = JUMP_RELEASE_CUT
}
@@ -100,7 +100,7 @@ update_player :: proc(p: ^Player, dt: f32) {
)
body.vel.y = math.min(body.vel.y + GRAVITY * dt, TERMINAL_VELOCITY)
- phys.update_body(&state.physics_world, p.body_handle)
+ phys.update_body(p.body_handle)
p.sprite.pos = body.pos
draw.update_sprite(&p.sprite, dt)
@@ -110,6 +110,6 @@ update_player :: proc(p: ^Player, dt: f32) {
}
draw_player :: proc(p: Player) {
- draw.sprite(&state.renderer, p.sprite)
+ draw.sprite(p.sprite)
}