abstracting to engine package

This commit is contained in:
2026-07-28 21:20:47 -07:00
parent fc1c39f4f2
commit 742cfcff6a
5 changed files with 246 additions and 104 deletions
+56
View File
@@ -0,0 +1,56 @@
package engine
import "core:fmt"
import sdl "vendor:sdl3"
App :: struct {
window: ^sdl.Window,
renderer: ^sdl.Renderer,
}
init :: proc(app: ^App, title: cstring, width, height: i32) -> bool {
if !sdl.Init({.VIDEO}) {
fmt.eprintfln("SDL_Init failed: %s", sdl.GetError())
return false
}
if !sdl.CreateWindowAndRenderer(title, width, height, {}, &app.window, &app.renderer) {
fmt.eprintfln("CreateWindowAndRenderer failed: %s", sdl.GetError())
return false
}
return true
}
shutdown :: proc(app: ^App) {
if app.renderer != nil do sdl.DestroyRenderer(app.renderer)
if app.window != nil do sdl.DestroyWindow(app.window)
sdl.Quit()
app^ = {}
}
pump_events :: proc() -> bool {
event: sdl.Event
for sdl.PollEvent(&event) {
if event.type == .QUIT {
return false
}
}
return true
}
begin_frame :: proc(app: ^App, r: u8 = 30, g: u8 = 30, b: u8 = 40, a: u8 = 255) {
sdl.SetRenderDrawColor(app.renderer, r, g, b, a)
sdl.RenderClear(app.renderer)
}
end_frame :: proc(app: ^App) {
sdl.RenderPresent(app.renderer)
}
renderer :: proc(app: ^App) -> ^sdl.Renderer {
return app.renderer
}
+108
View File
@@ -0,0 +1,108 @@
package engine
import "core:encoding/json"
import "core:fmt"
import "core:os"
import "core:path/filepath"
import "core:strings"
import sdl "vendor:sdl3"
Frame_Def :: struct {
rect: [4]int,
source_size: [2]int,
trim_offset: [2]int,
}
Clip_Def :: struct {
loop: bool,
fps: f32,
frames: []Frame_Def,
}
Char_Def :: struct {
version: int,
id: string,
atlas: string,
pixels_per_unit: f32,
pivot: [2]f32,
clips: map[string]Clip_Def,
}
Character_Data :: struct {
def: Char_Def,
texture: ^sdl.Texture,
}
load_character_data :: proc(
renderer: ^sdl.Renderer,
character_json_path: string,
) -> (
Character_Data,
bool,
) {
file_data, read_err := os.read_entire_file(character_json_path, context.allocator)
if read_err != nil {
fmt.eprintfln("failed to read %s: %v", character_json_path, read_err)
return {}, false
}
defer delete(file_data)
out: Character_Data
if err := json.unmarshal(file_data, &out.def); err != nil {
fmt.eprintfln("json unmarshal failed: %v", err)
return {}, false
}
// filepath.dir returns a substring of the path — do NOT delete it
dir := filepath.dir(character_json_path)
atlas_path, join_err := filepath.join({dir, out.def.atlas})
if join_err != nil {
fmt.eprintfln("atlas join failed: %v", join_err)
return {}, false
}
defer delete(atlas_path)
c_path := strings.clone_to_cstring(atlas_path)
defer delete(c_path)
surface := sdl.LoadPNG(c_path)
if surface == nil {
fmt.eprintfln("LoadPNG failed: %s", sdl.GetError())
return {}, false
}
defer sdl.DestroySurface(surface)
out.texture = sdl.CreateTextureFromSurface(renderer, surface)
if out.texture == nil {
fmt.eprintfln("CreateTextureFromSurface failed: %s", sdl.GetError())
return {}, false
}
sdl.SetTextureScaleMode(out.texture, .NEAREST)
return out, true
}
destroy_character_data :: proc(data: ^Character_Data) {
if data.texture != nil {
sdl.DestroyTexture(data.texture)
}
data^ = {}
}
character_frame_rect :: proc(
data: ^Character_Data,
clip_name: string,
frame_index: int,
) -> (
rect: [4]int,
ok: bool,
) {
clip, found := data.def.clips[clip_name]
if !found || frame_index < 0 || frame_index >= len(clip.frames) {
return {}, false
}
return clip.frames[frame_index].rect, true
}
+51
View File
@@ -0,0 +1,51 @@
package engine
import sdl "vendor:sdl3"
Vec2 :: [2]f32
Sprite :: struct {
data: ^Character_Data,
position: Vec2,
clip: string,
frame: int,
}
spawn_sprite :: proc(
data: ^Character_Data,
position: Vec2,
clip: string = "idle",
frame: int = 0,
) -> Sprite {
return Sprite{data = data, position = position, clip = clip, frame = frame}
}
// stubbed for later
update_sprite :: proc(sprite: ^Sprite, dt: f32) {
_ = sprite
_ = dt
}
draw_sprite :: proc(renderer: ^sdl.Renderer, sprite: ^Sprite) {
assert(sprite.data != nil)
rect, ok := character_frame_rect(sprite.data, sprite.clip, sprite.frame)
if !ok {
return
}
w := f32(rect[2])
h := f32(rect[3])
dst := sdl.FRect {
x = sprite.position.x - w * 0.5,
y = sprite.position.y - h,
w = w,
h = h,
}
src := sdl.FRect {
x = f32(rect[0]),
y = f32(rect[1]),
w = w,
h = h,
}
sdl.RenderTexture(renderer, sprite.data.texture, &src, &dst)
}