diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6e5660b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendors/odin-aseprite"] + path = vendors/odin-aseprite + url = git@github.com:blob1807/odin-aseprite.git diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index af68a68..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "cppvsdbg", - "request": "launch", - "preLaunchTask": "Build Debug", - "name": "Debug", - "program": "${workspaceFolder}/build/game_debug.exe", - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "cppvsdbg", - "request": "launch", - "preLaunchTask": "Build Release", - "name": "Release", - "program": "${workspaceFolder}/game_release.exe", - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "cppvsdbg", - "request": "launch", - "name": "Run File", - "program": "odin", - "args": ["run", "${fileBasename}", "-file"], - "cwd": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f7964b5..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "[odin]": { - "editor.formatOnSave": true, - "editor.tabSize": 4 - } -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 784b8a9..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "version": "2.0.0", - "command": "", - "args": [], - "tasks": [ - { - "label": "Build Debug", - "type": "shell", - "windows": { - "command": "${workspaceFolder}/scripts/build_debug.bat" - }, - "linux": { - "command": "${workspaceFolder}/scripts/build_debug.sh" - }, - "osx": { - "command": "${workspaceFolder}/scripts/build_debug.sh" - }, - "group": { - "kind": "build", - "isDefault": true - }, - "problemMatcher": [] - }, - { - "label": "Build Release", - "type": "shell", - "windows": { - "command": "${workspaceFolder}/scripts/build_release.bat" - }, - "linux": { - "command": "${workspaceFolder}/scripts/build_release.sh" - }, - "osx": { - "command": "${workspaceFolder}/scripts/build_release.sh" - }, - "group": "build" - }, - { - "label": "Clean build folder(s)", - "type": "shell", - "windows": { - "command": "cd ${workspaceFolder}\\build && rm game*; cd ${workspaceFolder} && rm aseprite_odin_generator*" - }, - "group": "build" - }, - { - "label": "Build Hot Reload", - "type": "shell", - "windows": { - "command": "${workspaceFolder}/scripts/build_hot_reload.bat; start game.exe" - }, - "linux": { - "command": "${workspaceFolder}/scripts/build_hot_reload.sh" - }, - "osx": { - "command": "${workspaceFolder}/scripts/build_hot_reload.sh" - }, - "presentation": { - "echo": true, - "reveal": "always", - "focus": false, - "panel": "dedicated", - "showReuseMessage": false, - "clear": true - }, - "group": "build", - "problemMatcher": [] - }, - { - "label": "Build&Run Atlas Generator Test", - "type": "shell", - "windows": { - "command": "${workspaceFolder}/scripts/build_generator_debug.bat && build_generator\\aseprite_odin_generator.exe -input-files:value_of_custom_arg -h" - }, - "options": { - "cwd": "${workspaceFolder}" - }, - "presentation": { - "echo": true, - "reveal": "always", - "focus": false, - "panel": "dedicated", - "showReuseMessage": false, - "clear": true - }, - "group": { - "kind": "build", - "isDefault": false - } - } - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 5f53772..faeb113 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,29 @@ # YAAP -Yet-Another-Atlas-Packer by Stefan Stefanov +Yet-Another-Atlas-Packer by bersK (Stefan Stefanov) + +## Usage & requirements +> [!IMPORTANT] +> Pull this repo with `--recursive`, the `odin-aseprite` library is pulled in as a submodule. + +* At least odin compiler version `dev-2025-07:204edd0fc` +* Build the `libtinyfiledialog` library in the `vendors/dialog` fold ## Description +> [!NOTE] +> Quite frankly if you want automatic atlas packing I would suggest using `stb_rect_pack` directly & an aseprite plugin for exporting your assets in a proper format for packing. Using this atlas packer in an automated fashion is not quite possible and slower as a workflow. I would only use it for experiment projects or places where having a built in atlas packer is not practical. -Simple atlas packer for .aseprite files. Generates metadata and potentially embeds in an output source file of your choosing. +Simple atlas packer for `.aseprite` files. Generates a packed png & metadata in the form of json and/or source files(cpp, odin, etc...). +> [!CAUTION] +> Does not handle palette files currently. -Uses `stb_rect_pack` from the `stb` family of header libraries & `raylib` for rendering/UI. Here's a quick preview on [youtube](https://youtu.be/4_dKq7G57Lw) of the application. +Uses `stb_rect_pack` for the image packing & `raylib` for the UI. - - - +A quick preview on [youtube](https://youtu.be/4_dKq7G57Lw). -The goal of the tool is to take in multiple aseprite files and pack them into a single atlas, outputting metadata in the process in the form of -JSON and/or source files for direct use in odin (or other languages through a customization file). + -I'm using a library for marshalling the aseprite files found [here](https://github.com/blob1807/odin-aseprite) on github. - -Project template provided by Karl Zylinski found [here](https://github.com/karl-zylinski/odin-raylib-hot-reload-game-template) on github. +## Dependencies +* odin-aseprite [github](https://github.com/blob1807/odin-aseprite) +* raylib (`vendor/raylib`, [link](https://github.com/odin-lang/Odin/tree/master/vendor/raylib)) +* stb_rect_pack (`vendor/stb/rect_pack`, [link](https://github.com/odin-lang/Odin/tree/master/vendor/stb/rect_pack)) diff --git a/examples/aseprite_odin_generator.odin b/examples/aseprite_odin_generator.odin index d400cc7..7180177 100644 --- a/examples/aseprite_odin_generator.odin +++ b/examples/aseprite_odin_generator.odin @@ -1,6 +1,6 @@ package cli -import ase "../vendors/aseprite" +import ase "../../vendors/odin-aseprite" import "core:encoding/json" import "core:fmt" import "core:os" diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 0000000..1bf5423 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,5 @@ +FLAGS="-define:RAYLIB_SHARED=true -out:build/yaap -debug" +SRC=src/frontend + +mkdir -p build +odin build ${SRC} ${FLAGS} \ No newline at end of file diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100644 index 0000000..81af715 --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh + +set -e + +pushd vendors/dialog +sh build.sh +popd \ No newline at end of file diff --git a/src/generator/generator.odin b/src/generator/generator.odin index 5e78041..34d6ab5 100644 --- a/src/generator/generator.odin +++ b/src/generator/generator.odin @@ -1,6 +1,6 @@ package generator -import ase "../../vendors/aseprite" +import ase "../../vendors/odin-aseprite" import "core:encoding/json" import "core:fmt" import "core:log" @@ -115,7 +115,7 @@ unmarshall_aseprite_files :: proc( if extension != ".aseprite" do continue log.infof("Unmarshalling file: ", file) - ase.unmarshal_from_filename(file, &aseprite_document, alloc) + ase.unmarshal_from_filename(&aseprite_document, file) atlas_entry := atlas_entry_from_compressed_cells(aseprite_document) atlas_entry.path = file @@ -147,7 +147,7 @@ atlas_entry_from_compressed_cells :: proc(document: ase.Document) -> (atlas_entr cell := CellData { img = rl.Image { - data = rawptr(&cel_img.pixel[0]), + data = rawptr(&cel_img.pixels[0]), width = auto_cast cel_img.width, height = auto_cast cel_img.height, format = .UNCOMPRESSED_R8G8B8A8, @@ -277,7 +277,7 @@ pack_atlas_entries :: proc( } cell_metadata := SpriteAtlasMetadata { name = cell_name, - location = { + location = { auto_cast rect.x + auto_cast offset_x, auto_cast rect.y + auto_cast offset_y, }, @@ -290,23 +290,23 @@ pack_atlas_entries :: proc( } odin_source_generator_metadata := SourceCodeGeneratorMetadata { - file_defines = { + file_defines = { top = "package atlas_bindings\n\n", bottom = "", file_name = "metadata", file_extension = ".odin", }, - custom_data_type = { + custom_data_type = { name = "AtlasRect", type_declaration = "%v :: struct {{ x, y, w, h: i32 }}\n\n", }, - enum_data = { + enum_data = { name = "AtlasEnum", begin_line = "%v :: enum {{\n", entry_line = "\t%s,\n", end_line = "}\n\n", }, - array_data = { + array_data = { name = "ATLAS_SPRITES", type = "[]AtlasRect", begin_line = "%v := %v {{\n", @@ -318,23 +318,23 @@ odin_source_generator_metadata := SourceCodeGeneratorMetadata { cpp_source_generator_metadata := SourceCodeGeneratorMetadata { - file_defines = { + file_defines = { top = "#include \n\n", bottom = "", file_name = "metadata", file_extension = ".hpp", }, - custom_data_type = { + custom_data_type = { name = "AtlasRect", type_declaration = "struct %v {{\n\tint x;\n\tint y;\n\tint w;\n\tint h;\n}};\n\n", }, - enum_data = { + enum_data = { name = "AtlasEnum", begin_line = "enum %v {{\n", entry_line = "\t%s,\n", end_line = "\n\tCOUNT\n}\n\n", }, - array_data = { + array_data = { name = "ATLAS_SPRITES", type = "AtlasRect[size_t(AtlasEnum::COUNT)-1]", begin_line = "{1} {0} = {{\n", @@ -516,7 +516,7 @@ save_metadata_simple :: proc( return } - metadata, ok := atlas_metadata.([dynamic]SpriteAtlasMetadata);if !ok { + metadata, ok := atlas_metadata.([dynamic]SpriteAtlasMetadata); if !ok { log.error("No metadata to export!") } @@ -542,7 +542,7 @@ save_metadata_simple :: proc( source_metadata := strings.to_string(sb) source_output_path := strings.concatenate( - { + { output_path, OS_FILE_SEPARATOR, codegen.file_defines.file_name, @@ -573,7 +573,7 @@ save_metadata :: proc( atlas_entries: []AtlasEntry, atlas_metadata: []SpriteAtlasMetadata, ) { - metadata, ok := settings.metadata.(CLIMetadataSettings);if !ok do return + metadata, ok := settings.metadata.(CLIMetadataSettings); if !ok do return if json_path, ok := metadata.json_path.(string); ok { json_bytes, jerr := json.marshal(atlas_metadata) diff --git a/vendors/aseprite b/vendors/aseprite deleted file mode 160000 index 628e655..0000000 --- a/vendors/aseprite +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 628e655661d822fecae67cf238cbfa414912d943 diff --git a/vendors/dialog/build.sh b/vendors/dialog/build.sh index 2eba996..bea45c2 100644 --- a/vendors/dialog/build.sh +++ b/vendors/dialog/build.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh gcc ./libtinyfiledialogs/tinyfiledialogs.c -c -o libtinyfiledialogs.o diff --git a/vendors/odin-aseprite b/vendors/odin-aseprite new file mode 160000 index 0000000..72ea2e8 --- /dev/null +++ b/vendors/odin-aseprite @@ -0,0 +1 @@ +Subproject commit 72ea2e8094a5f05074d4c4f2faafdba42e54673c