abstracting to engine package
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user