Last active
January 12, 2024 17:31
-
-
Save Tekkunsan/4f41b1cf41acd6a69f30acacc43f5176 to your computer and use it in GitHub Desktop.
Basic Ogmo Loader for Odin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Bindings for Ogmo3 | |
package ogmo | |
import "core:encoding/json" | |
import "core:log" | |
import "core:os" | |
loadProject :: proc(filename: string, allocator := context.allocator) -> (res: Project, ok: bool) { | |
data, dOk := os.read_entire_file(filename, allocator) | |
if !dOk { | |
log.error("Failed to load:", filename) | |
return | |
} | |
return loadProjectFromMemory(data, allocator) | |
} | |
loadProjectFromMemory :: proc( | |
data: []byte, | |
allocator := context.allocator, | |
) -> ( | |
res: Project, | |
ok: bool, | |
) { | |
err := json.unmarshal(data, &res, json.DEFAULT_SPECIFICATION, allocator) | |
if err != nil { | |
log.error("Failed to parse project json:", err) | |
return | |
} | |
return res, true | |
} | |
loadLevel :: proc(filename: string, allocator := context.allocator) -> (res: Level, ok: bool) { | |
data, dOk := os.read_entire_file(filename, allocator) | |
if !dOk { | |
log.error("Failed to load:", filename) | |
return | |
} | |
return loadLevelFromMemory(data, allocator) | |
} | |
loadLevelFromMemory :: proc( | |
data: []byte, | |
allocator := context.allocator, | |
) -> ( | |
res: Level, | |
ok: bool, | |
) { | |
err := json.unmarshal(data, &res, json.DEFAULT_SPECIFICATION, allocator) | |
if err != nil { | |
log.error("Failed to parse project json:", err) | |
return | |
} | |
return res, true | |
} | |
Project :: struct { | |
name: string, | |
ogmoVersion: string, | |
levelPaths: []string, | |
backgroundColor: string, | |
gridColor: string, | |
anglesRadians: bool, | |
directoryDepth: u32, | |
layerGridDefaultSize: Point2, | |
levelDefaultSize: Point2, | |
levelMinSize: Point2, | |
levelMaxSize: Point2, | |
layers: []ProjectLayer, | |
entities: []ProjectEntity, | |
tilesets: []Tileset, | |
} | |
ProjectLayer :: struct { | |
definition: string, | |
name: string, | |
gridSize: Point2, | |
exportID: string, | |
exportMode: Maybe(u32), | |
arrayMode: Maybe(u32), | |
defaultTileset: Maybe(string), | |
} | |
ProjectEntity :: struct { | |
name: string, | |
limit: int, | |
size: Point2, | |
origin: Point2, | |
shape: Shape, | |
color: string, | |
rotatable: bool, | |
tags: []string, | |
values: []Value, | |
exportID: string, | |
originAnchored: bool, | |
tileX: bool, | |
tileY: bool, | |
tileSize: Point2, | |
resizeableX: bool, | |
resizeableY: bool, | |
rotationDegrees: int, | |
canFlipX: bool, | |
canFlipY: bool, | |
canSetColor: bool, | |
hasNodes: bool, | |
nodeLimit: u32, | |
nodeDisplay: u32, | |
nodeGhost: bool, | |
} | |
Shape :: struct { | |
label: string, | |
points: []Point2, | |
} | |
Value :: struct { | |
name: string, | |
definition: string, | |
defaults: string, | |
bounded: Maybe(bool), | |
min: Maybe(u32), | |
max: Maybe(u32), | |
trimWhitespace: Maybe(bool), | |
maxLength: Maybe(u32), | |
} | |
Tileset :: struct { | |
label: string, | |
path: string, | |
tileWidth: u32, | |
tileHeight: u32, | |
tileSeparationX: u32, | |
tileSeparationY: u32, | |
} | |
Level :: struct { | |
ogmoVersion: string, | |
width: u32, | |
height: u32, | |
offsetX: u32, | |
offsetY: u32, | |
layers: []LevelLayer, | |
} | |
LevelLayer :: struct { | |
name: string, | |
entities: Maybe([]LevelEntity), | |
tileset: Maybe(string), | |
data: Maybe([]i32), | |
_eid: string, | |
offsetX: u32, | |
offsetY: u32, | |
gridCellWidth: u32, | |
gridCellHeight: u32, | |
gridCellsX: u32, | |
gridCellsY: u32, | |
exportMode: Maybe(u32), | |
arrayMode: Maybe(u32), | |
} | |
LevelEntity :: struct { | |
name: string, | |
id: u32, | |
_eid: string, | |
x: int, | |
y: int, | |
originX: int, | |
originY: int, | |
values: Maybe(map[string]string), | |
} | |
Point2 :: struct { | |
x, y: i32, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ogmo | |
import "core:log" | |
import "core:strings" | |
import rl "vendor:raylib" | |
lvl_drawToTexture :: proc(project: Project, level: Level) -> (res: rl.RenderTexture2D) { | |
res = rl.LoadRenderTexture(i32(level.width), i32(level.height)) | |
rl.BeginTextureMode(res) | |
rl.ClearBackground(rl.BLANK) | |
for levelLayer in level.layers { | |
if lvlData, ok := levelLayer.data.?; ok { | |
assert(levelLayer.arrayMode.? == 0, "Level's Array mode must be 1D") | |
// Yeah... THis leaks... | |
tilesetTexture, found := getTilesetTexture(project, levelLayer.tileset.?) | |
assert(found, "Failed to found the tileset") | |
// defer rl.UnloadTexture(tilesetTexture) | |
draw( | |
project, | |
level.width, | |
level.height, | |
levelLayer.gridCellWidth, | |
levelLayer.gridCellHeight, | |
lvlData, | |
tilesetTexture, | |
) | |
} else do continue | |
} | |
rl.EndTextureMode() | |
return res | |
} | |
lvl_getSrcAndDest :: proc( | |
levelTexture: rl.RenderTexture2D, | |
x, y: f32, | |
) -> ( | |
src, dest: rl.Rectangle, | |
) { | |
src = {0, 0, f32(levelTexture.texture.width), -f32(levelTexture.texture.height)} | |
dest = {x, y, f32(levelTexture.texture.width), f32(levelTexture.texture.height)} | |
return | |
} | |
@(private) | |
draw :: proc( | |
project: Project, | |
width, height, cellSizeW, cellSizeH: u32, | |
lvlData: []i32, | |
tilesetTexture: rl.Texture2D, | |
) { | |
w := width / cellSizeW | |
h := height / cellSizeH | |
for y in 0 ..< h { | |
for x in 0 ..< w { | |
data := lvlData[x + w * y] | |
srcRect: rl.Rectangle | |
srcRect.width = f32(cellSizeW) | |
srcRect.height = f32(cellSizeH) | |
switch data { | |
case -1 ..= 0: | |
continue | |
case: | |
// TODO: This will definetely not work all the time please future proof this | |
srcRect.x = f32(data * i32(cellSizeW)) | |
} | |
log.info(srcRect) | |
destRect := rl.Rectangle { | |
f32(x * cellSizeW), | |
f32(y * cellSizeH), | |
f32(cellSizeW), | |
f32(cellSizeH), | |
} | |
rl.DrawTexturePro(tilesetTexture, srcRect, destRect, {0, 0}, 0, rl.WHITE) | |
} | |
} | |
} | |
@(private) | |
getTilesetTexture :: proc(project: Project, label: string) -> (res: rl.Texture2D, found: bool) { | |
for tileset in project.tilesets { | |
if tileset.label == label { | |
concat := strings.concatenate({"assets/data/", tileset.path}, context.temp_allocator) | |
cStr := strings.clone_to_cstring(concat, context.temp_allocator) | |
res = rl.LoadTexture(cStr) | |
return res, true | |
} | |
} | |
return res, false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment