More cleanup. Hooray!
This commit is contained in:
parent
faf42da522
commit
a51f5c6b57
4 changed files with 180 additions and 251 deletions
|
|
@ -4,10 +4,12 @@ import generator "../generator"
|
|||
import rl "vendor:raylib"
|
||||
|
||||
PIXEL_WINDOW_HEIGHT :: 180
|
||||
FILE_DIALOG_SIZE :: 1000
|
||||
|
||||
scaling: f32 = 2
|
||||
|
||||
@(rodata)
|
||||
ATLAS_RENDER_SIZES := []i32{256, 512, 1024, 2048, 4096}
|
||||
|
||||
WindowInformation :: struct {
|
||||
w: f32,
|
||||
h: f32,
|
||||
|
|
@ -22,9 +24,7 @@ MonitorInformation :: struct {
|
|||
|
||||
FileDialogType :: enum {
|
||||
SourceFiles,
|
||||
SourceFolder,
|
||||
OutputFolder,
|
||||
SaveFileAs,
|
||||
}
|
||||
|
||||
PackerSettings :: struct {
|
||||
|
|
@ -37,28 +37,16 @@ PackerSettings :: struct {
|
|||
output_odin: bool,
|
||||
}
|
||||
|
||||
ApplicationState :: struct {
|
||||
file_dialog_text_buffer: [FILE_DIALOG_SIZE + 1]u8,
|
||||
is_packing_whole_source_folder: bool,
|
||||
should_open_file_dialog: bool,
|
||||
window_info: WindowInformation,
|
||||
monitor_info: MonitorInformation,
|
||||
// Where the output files will be written (atlas.png, json output, etc)
|
||||
output_folder_path: Maybe(string),
|
||||
// If files were chosen as input - their paths
|
||||
source_location_to_pack: Maybe(string),
|
||||
// If a folder was chosen as input - the path
|
||||
source_files_to_pack: Maybe([]string),
|
||||
// What type of file dialog to open
|
||||
source_location_type: FileDialogType,
|
||||
// Packer settings
|
||||
packer_settings: PackerSettings,
|
||||
atlas_render_texture_target: rl.RenderTexture2D,
|
||||
atlas_checked_background: rl.RenderTexture2D,
|
||||
should_render_atlas: bool,
|
||||
atlas_render_has_preview: bool,
|
||||
atlas_render_size: i32,
|
||||
atlas_metadata: Maybe([dynamic]generator.SpriteAtlasMetadata),
|
||||
}
|
||||
|
||||
g_mem: ApplicationState
|
||||
window_info: WindowInformation
|
||||
monitor_info: MonitorInformation
|
||||
// Where the output files will be written (atlas.png json output, etc)
|
||||
output_folder_path: Maybe(string)
|
||||
// If a folder was chosen as input - the path
|
||||
source_files_to_pack: Maybe([]string)
|
||||
// Packer settings
|
||||
packer_settings: PackerSettings
|
||||
atlas_render_texture_target: rl.RenderTexture2D
|
||||
atlas_checked_background: rl.RenderTexture2D
|
||||
atlas_render_has_preview: bool
|
||||
atlas_render_size: i32
|
||||
atlas_metadata: Maybe([dynamic]generator.SpriteAtlasMetadata)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package frontend
|
||||
|
||||
import "base:runtime"
|
||||
import "core:c/libc"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:math"
|
||||
|
|
@ -12,59 +14,58 @@ import rl "vendor:raylib"
|
|||
import diag "../../vendors/dialog"
|
||||
import generator "../generator"
|
||||
|
||||
should_pack_atlas_and_render: bool
|
||||
|
||||
main :: proc() {
|
||||
default_allocator := context.allocator
|
||||
tracking_allocator: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&tracking_allocator, default_allocator)
|
||||
context.allocator = mem.tracking_allocator(&tracking_allocator)
|
||||
|
||||
mode: int = 0
|
||||
when ODIN_OS == .Linux || ODIN_OS == .Darwin {
|
||||
mode = os.S_IRUSR | os.S_IWUSR | os.S_IRGRP | os.S_IROTH
|
||||
}
|
||||
context.logger = log.create_console_logger()
|
||||
{
|
||||
init()
|
||||
|
||||
logh, logh_err := os.open("log.txt", (os.O_CREATE | os.O_TRUNC | os.O_RDWR), mode)
|
||||
defer cleanup()
|
||||
|
||||
if logh_err == os.ERROR_NONE {
|
||||
os.stdout = logh
|
||||
os.stderr = logh
|
||||
}
|
||||
for !rl.WindowShouldClose() {
|
||||
update()
|
||||
draw()
|
||||
|
||||
logger :=
|
||||
logh_err == os.ERROR_NONE ? log.create_file_logger(logh) : log.create_console_logger()
|
||||
context.logger = logger
|
||||
defer if logh_err == os.ERROR_NONE {
|
||||
log.destroy_file_logger(logger)
|
||||
for b in tracking_allocator.bad_free_array {
|
||||
log.errorf("Bad free at: %v", b.location)
|
||||
}
|
||||
|
||||
clear(&tracking_allocator.bad_free_array)
|
||||
|
||||
free_all(context.temp_allocator)
|
||||
}
|
||||
}
|
||||
log.destroy_console_logger(context.logger)
|
||||
|
||||
for key, value in tracking_allocator.allocation_map {
|
||||
log.errorf("%v: Leaked %v bytes\n", value.location, value.size)
|
||||
}
|
||||
mem.tracking_allocator_destroy(&tracking_allocator)
|
||||
}
|
||||
|
||||
init :: proc() {
|
||||
atlas_render_size = ATLAS_RENDER_SIZES[0]
|
||||
|
||||
rl.SetConfigFlags({.WINDOW_RESIZABLE})
|
||||
rl.InitWindow(1400, 800, "YAAP - Yet Another Atlas Packer")
|
||||
defer rl.CloseWindow()
|
||||
rl.SetWindowMinSize(1400, 800)
|
||||
rl.SetTraceLogCallback(rl_log)
|
||||
}
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
update()
|
||||
draw()
|
||||
|
||||
for b in tracking_allocator.bad_free_array {
|
||||
log.error("Bad free at: %v", b.location)
|
||||
}
|
||||
|
||||
clear(&tracking_allocator.bad_free_array)
|
||||
|
||||
free_all(context.temp_allocator)
|
||||
}
|
||||
|
||||
for key, value in tracking_allocator.allocation_map {
|
||||
log.error("%v: Leaked %v bytes\n", value.location, value.size)
|
||||
}
|
||||
|
||||
mem.tracking_allocator_destroy(&tracking_allocator)
|
||||
cleanup :: proc() {
|
||||
log.info("Bye")
|
||||
rl.CloseWindow()
|
||||
}
|
||||
|
||||
update :: proc() {
|
||||
// Update the width/height
|
||||
win_info := &g_mem.window_info
|
||||
win_info := &window_info
|
||||
win_info.w = f32(rl.GetScreenWidth())
|
||||
win_info.h = f32(rl.GetScreenHeight())
|
||||
win_info.height_scaled = win_info.h / scaling
|
||||
|
|
@ -73,10 +74,6 @@ update :: proc() {
|
|||
// Update the virtual mouse position (needed for GUI interaction to work properly for instance)
|
||||
mouse_scale := 1 / scaling
|
||||
rl.SetMouseScale(mouse_scale, mouse_scale)
|
||||
|
||||
if g_mem.should_open_file_dialog {
|
||||
open_file_dialog()
|
||||
}
|
||||
}
|
||||
|
||||
draw :: proc() {
|
||||
|
|
@ -87,8 +84,8 @@ draw :: proc() {
|
|||
|
||||
draw_screen_ui()
|
||||
|
||||
if g_mem.should_render_atlas {
|
||||
draw_screen_target()
|
||||
if should_pack_atlas_and_render {
|
||||
pack_atlas_and_render()
|
||||
}
|
||||
|
||||
free_all(context.temp_allocator)
|
||||
|
|
@ -100,41 +97,23 @@ ui_camera :: proc() -> rl.Camera2D {
|
|||
|
||||
draw_screen_ui :: proc() {
|
||||
rl.BeginMode2D(ui_camera())
|
||||
defer rl.EndMode2D()
|
||||
|
||||
draw_atlas_settings_and_preview()
|
||||
draw_settings_and_preview()
|
||||
|
||||
rl.EndMode2D()
|
||||
}
|
||||
|
||||
pick_sources :: proc() {
|
||||
g_mem.should_open_file_dialog = true
|
||||
g_mem.source_location_type = .SourceFiles
|
||||
save_atlas_to_file :: proc() {
|
||||
generator.save_output(output_folder_path, atlas_metadata, atlas_render_texture_target)
|
||||
}
|
||||
|
||||
pick_output :: proc() {
|
||||
g_mem.should_open_file_dialog = true
|
||||
g_mem.source_location_type = .OutputFolder
|
||||
save_to_atlas_to_file :: proc() {
|
||||
open_file_dialog(.OutputFolder)
|
||||
save_atlas_to_file()
|
||||
}
|
||||
|
||||
pack_atlas :: proc() {
|
||||
g_mem.should_render_atlas = true
|
||||
}
|
||||
|
||||
save :: proc() {
|
||||
generator.save_output(
|
||||
g_mem.output_folder_path,
|
||||
g_mem.atlas_metadata,
|
||||
g_mem.atlas_render_texture_target,
|
||||
)
|
||||
}
|
||||
|
||||
save_to :: proc() {
|
||||
// if output_folder, ok := g_mem.output_folder_path.(string); ok {
|
||||
// generator.save_metadata_simple(output_folder, g_mem.atlas_metadata, nil, nil, nil)
|
||||
// }
|
||||
}
|
||||
|
||||
draw_screen_target :: proc() {
|
||||
atlas_render_target := &g_mem.atlas_render_texture_target
|
||||
pack_atlas_and_render :: proc() {
|
||||
atlas_render_target := &atlas_render_texture_target
|
||||
|
||||
rl.BeginTextureMode(atlas_render_target^)
|
||||
defer rl.EndTextureMode()
|
||||
|
|
@ -142,28 +121,21 @@ draw_screen_target :: proc() {
|
|||
atlas_entries: [dynamic]generator.AtlasEntry
|
||||
delete(atlas_entries)
|
||||
|
||||
if files, ok := g_mem.source_files_to_pack.([]string); ok {
|
||||
if files, ok := source_files_to_pack.([]string); ok {
|
||||
generator.unmarshall_aseprite_files(files, &atlas_entries)
|
||||
} else {
|
||||
log.error("No source folder or files set! Can't pack the void!!!")
|
||||
g_mem.should_render_atlas = false
|
||||
should_pack_atlas_and_render = false
|
||||
return
|
||||
}
|
||||
|
||||
atlas: rl.Image = rl.GenImageColor(g_mem.atlas_render_size, g_mem.atlas_render_size, rl.BLANK)
|
||||
atlas: rl.Image = rl.GenImageColor(atlas_render_size, atlas_render_size, rl.BLANK)
|
||||
// defer rl.UnloadImage(atlas)
|
||||
|
||||
padding_x :=
|
||||
g_mem.packer_settings.pixel_padding_x_int if g_mem.packer_settings.padding_enabled else 0
|
||||
padding_y :=
|
||||
g_mem.packer_settings.pixel_padding_y_int if g_mem.packer_settings.padding_enabled else 0
|
||||
padding_x := packer_settings.pixel_padding_x_int if packer_settings.padding_enabled else 0
|
||||
padding_y := packer_settings.pixel_padding_y_int if packer_settings.padding_enabled else 0
|
||||
|
||||
g_mem.atlas_metadata = generator.pack_atlas_entries(
|
||||
atlas_entries[:],
|
||||
&atlas,
|
||||
padding_x,
|
||||
padding_y,
|
||||
)
|
||||
atlas_metadata = generator.pack_atlas_entries(atlas_entries[:], &atlas, padding_x, padding_y)
|
||||
|
||||
// OpenGL's Y buffer is flipped
|
||||
rl.ImageFlipVertical(&atlas)
|
||||
|
|
@ -171,28 +143,27 @@ draw_screen_target :: proc() {
|
|||
log.info("Packed everything!")
|
||||
atlas_render_target.texture = rl.LoadTextureFromImage(atlas)
|
||||
|
||||
g_mem.should_render_atlas = false
|
||||
g_mem.atlas_render_has_preview = true
|
||||
should_pack_atlas_and_render = false
|
||||
atlas_render_has_preview = true
|
||||
}
|
||||
|
||||
draw_atlas_settings_and_preview :: proc() {
|
||||
draw_settings_and_preview :: proc() {
|
||||
left_half_rect := rl.Rectangle {
|
||||
x = 0,
|
||||
y = 0,
|
||||
width = cast(f32)g_mem.window_info.width_scaled / 3,
|
||||
height = cast(f32)g_mem.window_info.height_scaled,
|
||||
width = cast(f32)window_info.width_scaled / 3,
|
||||
height = cast(f32)window_info.height_scaled,
|
||||
}
|
||||
right_half_rect := rl.Rectangle {
|
||||
x = cast(f32)g_mem.window_info.width_scaled / 3,
|
||||
x = cast(f32)window_info.width_scaled / 3,
|
||||
y = 0,
|
||||
width = cast(f32)(g_mem.window_info.width_scaled / 3) * 2,
|
||||
height = cast(f32)g_mem.window_info.height_scaled,
|
||||
width = cast(f32)(window_info.width_scaled / 3) * 2,
|
||||
height = cast(f32)window_info.height_scaled,
|
||||
}
|
||||
rl.DrawRectangleRec(left_half_rect, rl.WHITE)
|
||||
rl.DrawRectangleRec(right_half_rect, rl.MAROON)
|
||||
|
||||
@(static)
|
||||
spinner_edit_mode: bool
|
||||
@(static) spinner_edit_mode: bool
|
||||
|
||||
small_offset := 10 * scaling
|
||||
big_offset := 30 * scaling
|
||||
|
|
@ -201,10 +172,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
rl.GuiPanel(left_half_rect, "Atlas Settings")
|
||||
elements_height += small_offset / 2
|
||||
|
||||
@(static)
|
||||
SettingsDropBoxEditMode: bool
|
||||
@(static)
|
||||
SettingsDropdownBoxActive: i32
|
||||
@(static) settings_dropdown_box_active_idx: i32
|
||||
|
||||
elements_height += small_offset + 5 * scaling
|
||||
|
||||
|
|
@ -214,10 +182,8 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
)
|
||||
elements_height += small_offset / 2
|
||||
|
||||
@(static)
|
||||
dropdown_resolution_edit_mode: bool
|
||||
@(static)
|
||||
dropdown_resolution_mode: i32
|
||||
@(static) dropdown_resolution_edit_mode: bool
|
||||
@(static) dropdown_resolution_mode: i32
|
||||
|
||||
dropdown_rect := rl.Rectangle {
|
||||
x = small_offset,
|
||||
|
|
@ -230,21 +196,21 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
if dropdown_resolution_edit_mode {rl.GuiLock()}
|
||||
|
||||
if rl.GuiDropdownBox(
|
||||
dropdown_rect,
|
||||
"256x;512x;1024x;2048x;4096x",
|
||||
&dropdown_resolution_mode,
|
||||
dropdown_resolution_edit_mode,
|
||||
) {
|
||||
dropdown_rect,
|
||||
"256x;512x;1024x;2048x;4096x",
|
||||
&dropdown_resolution_mode,
|
||||
dropdown_resolution_edit_mode,
|
||||
) {
|
||||
dropdown_resolution_edit_mode = !dropdown_resolution_edit_mode
|
||||
g_mem.atlas_render_size = 256 * auto_cast math.pow(2, f32(dropdown_resolution_mode))
|
||||
atlas_render_size =
|
||||
ATLAS_RENDER_SIZES[max(i32(len(ATLAS_RENDER_SIZES) - 1), dropdown_resolution_mode)]
|
||||
}
|
||||
rl.GuiUnlock()
|
||||
}
|
||||
elements_height += small_offset * 2
|
||||
|
||||
|
||||
// General Options
|
||||
if SettingsDropdownBoxActive == 0 {
|
||||
if settings_dropdown_box_active_idx == 0 {
|
||||
padding_settings_y := elements_height
|
||||
{
|
||||
defer {
|
||||
|
|
@ -267,7 +233,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
rl.GuiCheckBox(
|
||||
enable_padding_rect,
|
||||
" Enable padding",
|
||||
&g_mem.packer_settings.padding_enabled,
|
||||
&packer_settings.padding_enabled,
|
||||
)
|
||||
elements_height += small_offset * 2
|
||||
|
||||
|
|
@ -282,7 +248,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
padding_x_spinner := rl.GuiSpinner(
|
||||
padding_x_spinner_rect,
|
||||
"",
|
||||
&g_mem.packer_settings.pixel_padding_x_int,
|
||||
&packer_settings.pixel_padding_x_int,
|
||||
0,
|
||||
10,
|
||||
spinner_edit_mode,
|
||||
|
|
@ -291,7 +257,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
spinner_edit_mode = !spinner_edit_mode
|
||||
}
|
||||
rl.GuiLabel(
|
||||
{
|
||||
{
|
||||
x = (small_offset * 2) + big_offset * 2,
|
||||
y = elements_height,
|
||||
width = big_offset,
|
||||
|
|
@ -313,7 +279,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
padding_y_spinner := rl.GuiSpinner(
|
||||
padding_y_spinner_rect,
|
||||
"",
|
||||
&g_mem.packer_settings.pixel_padding_y_int,
|
||||
&packer_settings.pixel_padding_y_int,
|
||||
0,
|
||||
10,
|
||||
spinner_edit_mode,
|
||||
|
|
@ -322,7 +288,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
spinner_edit_mode = !spinner_edit_mode
|
||||
}
|
||||
rl.GuiLabel(
|
||||
{
|
||||
{
|
||||
x = (small_offset * 2) + big_offset * 2,
|
||||
y = elements_height,
|
||||
width = big_offset,
|
||||
|
|
@ -336,9 +302,6 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
}
|
||||
elements_height += small_offset
|
||||
|
||||
// rl.GuiLine({y = elements_height, width = left_half_rect.width}, "Actions")
|
||||
// elements_height += small_offset
|
||||
|
||||
{
|
||||
actions_label_y := elements_height
|
||||
|
||||
|
|
@ -360,7 +323,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
height = small_offset,
|
||||
}
|
||||
if rl.GuiButton(pick_sources_rect, "Pick Source(s)") {
|
||||
pick_sources()
|
||||
open_file_dialog(.SourceFiles)
|
||||
}
|
||||
|
||||
pick_output_rect := rl.Rectangle {
|
||||
|
|
@ -370,7 +333,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
height = small_offset,
|
||||
}
|
||||
if rl.GuiButton(pick_output_rect, "Pick Output") {
|
||||
pick_output()
|
||||
open_file_dialog(.OutputFolder)
|
||||
}
|
||||
elements_height += small_offset * 2
|
||||
|
||||
|
|
@ -381,7 +344,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
height = small_offset,
|
||||
}
|
||||
if rl.GuiButton(pack_atlas_rect, "Pack Atlas") {
|
||||
pack_atlas()
|
||||
should_pack_atlas_and_render = true
|
||||
}
|
||||
|
||||
clear_atlas_rect := rl.Rectangle {
|
||||
|
|
@ -402,7 +365,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
height = small_offset,
|
||||
}
|
||||
if rl.GuiButton(save_rect, "Save") {
|
||||
save()
|
||||
save_atlas_to_file()
|
||||
}
|
||||
|
||||
save_to_rect := rl.Rectangle {
|
||||
|
|
@ -412,7 +375,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
height = small_offset,
|
||||
}
|
||||
if rl.GuiButton(save_to_rect, "Save To...") {
|
||||
save_to()
|
||||
save_to_atlas_to_file()
|
||||
}
|
||||
elements_height += small_offset * 2
|
||||
}
|
||||
|
|
@ -420,10 +383,9 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
}
|
||||
|
||||
// Packing Options
|
||||
if SettingsDropdownBoxActive == 1 {
|
||||
if settings_dropdown_box_active_idx == 1 {
|
||||
|
||||
@(static)
|
||||
active_tab: i32
|
||||
@(static) active_tab: i32
|
||||
tabs: []cstring = {"One", "Two", "Three"}
|
||||
rl.GuiTabBar(
|
||||
{x = small_offset, y = elements_height, width = 100, height = small_offset},
|
||||
|
|
@ -434,9 +396,8 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
}
|
||||
|
||||
// Save Options
|
||||
if SettingsDropdownBoxActive == 2 {
|
||||
|
||||
}
|
||||
// if settings_dropdown_box_active_idx == 2 {
|
||||
// }
|
||||
|
||||
elements_height = 0
|
||||
rl.GuiPanel(right_half_rect, "Atlas Preview")
|
||||
|
|
@ -450,11 +411,11 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
width = short_edge,
|
||||
height = short_edge,
|
||||
}
|
||||
if !g_mem.atlas_render_has_preview {
|
||||
if !atlas_render_has_preview {
|
||||
rl.GuiDummyRec(preview_rect, "PREVIEW")
|
||||
} else {
|
||||
// rl.DrawRectangleRec(preview_rect, rl.WHITE)
|
||||
bg_texture := g_mem.atlas_checked_background.texture
|
||||
bg_texture := atlas_checked_background.texture
|
||||
rl.DrawTexturePro(
|
||||
bg_texture,
|
||||
{width = auto_cast bg_texture.width, height = auto_cast bg_texture.height},
|
||||
|
|
@ -463,9 +424,7 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
0,
|
||||
rl.WHITE,
|
||||
)
|
||||
// preview_rect.x +=
|
||||
// 10;preview_rect.y += 10;preview_rect.height -= 20;preview_rect.width -= 20
|
||||
atlas_texture := g_mem.atlas_render_texture_target.texture
|
||||
atlas_texture := atlas_render_texture_target.texture
|
||||
rl.DrawTexturePro(
|
||||
atlas_texture,
|
||||
{width = auto_cast atlas_texture.width, height = auto_cast -atlas_texture.height},
|
||||
|
|
@ -477,96 +436,80 @@ draw_atlas_settings_and_preview :: proc() {
|
|||
}
|
||||
}
|
||||
|
||||
open_file_dialog :: proc() {
|
||||
switch g_mem.source_location_type {
|
||||
open_file_dialog :: proc(dialog_type: FileDialogType) {
|
||||
switch dialog_type {
|
||||
case .SourceFiles:
|
||||
// `open_file_dialog` returns a single cstring with one or more paths, divided by a separator ('|'),
|
||||
// `open_file_dialog` returns a single cstring with one or more paths divided by a separator ('|'),
|
||||
// https://github.com/native-toolkit/libtinyfiledialogs/blob/master/tinyfiledialogs.c#L2706
|
||||
file_paths_conc := cstring(
|
||||
diag.open_file_dialog(
|
||||
"Select source files",
|
||||
cstring(&g_mem.file_dialog_text_buffer[0]),
|
||||
0,
|
||||
nil,
|
||||
"",
|
||||
1,
|
||||
),
|
||||
diag.open_file_dialog("Select source files", nil, 0, nil, "", 1),
|
||||
)
|
||||
if len(file_paths_conc) > 0 {
|
||||
// todo(stefan): Currently we're not doing any checks if the filepaths are valid at all,
|
||||
// this should be fine because it's returned by the OS' file picker but who knows...
|
||||
source_files_to_pack := strings.clone_from_cstring(file_paths_conc, context.allocator)
|
||||
g_mem.source_files_to_pack = strings.split(source_files_to_pack, "|")
|
||||
// todo(stefan): We're assuming the filepaths returned libtinydialog are valid...
|
||||
source_files := strings.clone_from_cstring(file_paths_conc, context.allocator)
|
||||
source_files_to_pack = strings.split(source_files, "|")
|
||||
|
||||
log.info(g_mem.source_files_to_pack)
|
||||
log.info(source_files_to_pack)
|
||||
} else {
|
||||
log.error("No files were selected!")
|
||||
}
|
||||
|
||||
case .SourceFolder:
|
||||
file := cstring(
|
||||
diag.select_folder_dialog(
|
||||
"Select source folder",
|
||||
cstring(&g_mem.file_dialog_text_buffer[0]),
|
||||
),
|
||||
)
|
||||
if len(file) > 0 {
|
||||
g_mem.source_location_to_pack = strings.clone_from_cstring(file)
|
||||
log.info(g_mem.source_location_to_pack)
|
||||
} else {
|
||||
log.error("Got an empty path from the file dialog!")
|
||||
}
|
||||
|
||||
case .OutputFolder:
|
||||
file := cstring(
|
||||
diag.select_folder_dialog(
|
||||
"Select source folder",
|
||||
cstring(&g_mem.file_dialog_text_buffer[0]),
|
||||
),
|
||||
)
|
||||
file := cstring(diag.select_folder_dialog("Select source folder", nil))
|
||||
if len(file) > 0 {
|
||||
g_mem.output_folder_path = strings.clone_from_cstring(file)
|
||||
log.info(g_mem.output_folder_path)
|
||||
output_folder_path = strings.clone_from_cstring(file)
|
||||
log.info(output_folder_path)
|
||||
} else {
|
||||
log.error("Got an empty path from the file dialog!")
|
||||
}
|
||||
|
||||
case .SaveFileAs:
|
||||
file_path: cstring
|
||||
patterns: []cstring = {"*.png"}
|
||||
if default_path, ok := g_mem.output_folder_path.(string); ok {
|
||||
default_path_filename := strings.concatenate(
|
||||
{default_path, generator.OS_FILE_SEPARATOR, "atlas.png"},
|
||||
)
|
||||
default_path_to_save: cstring = strings.clone_to_cstring(default_path_filename)
|
||||
file_path = cstring(
|
||||
diag.save_file_dialog(
|
||||
"Save as...",
|
||||
default_path_to_save,
|
||||
1,
|
||||
&patterns[0],
|
||||
"Atlas",
|
||||
),
|
||||
)
|
||||
} else {
|
||||
file_path = cstring(diag.save_file_dialog("Save as...", "", 1, &patterns[0], "Atlas"))
|
||||
}
|
||||
if file_path != nil {
|
||||
generator.save_output(
|
||||
g_mem.output_folder_path,
|
||||
g_mem.atlas_metadata,
|
||||
g_mem.atlas_render_texture_target,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
g_mem.should_open_file_dialog = false
|
||||
}
|
||||
|
||||
clear_atlas_data :: proc() {
|
||||
if metadata, ok := g_mem.atlas_metadata.([dynamic]generator.SpriteAtlasMetadata); ok {
|
||||
if metadata, ok := atlas_metadata.([dynamic]generator.SpriteAtlasMetadata); ok {
|
||||
delete(metadata)
|
||||
}
|
||||
g_mem.atlas_render_has_preview = false
|
||||
atlas_render_has_preview = false
|
||||
}
|
||||
logger: log.Logger
|
||||
rl_log_buf: []byte
|
||||
rl_log :: proc "c" (logLevel: rl.TraceLogLevel, text: cstring, args: ^libc.va_list) {
|
||||
context = runtime.default_context()
|
||||
context.logger = logger
|
||||
|
||||
level: log.Level
|
||||
switch logLevel {
|
||||
case .TRACE, .DEBUG:
|
||||
level = .Debug
|
||||
case .ALL, .NONE, .INFO:
|
||||
level = .Info
|
||||
case .WARNING:
|
||||
level = .Warning
|
||||
case .ERROR:
|
||||
level = .Error
|
||||
case .FATAL:
|
||||
level = .Fatal
|
||||
}
|
||||
|
||||
if level < logger.lowest_level {
|
||||
return
|
||||
}
|
||||
|
||||
if rl_log_buf == nil {
|
||||
rl_log_buf = make([]byte, 1024)
|
||||
}
|
||||
|
||||
defer mem.zero_slice(rl_log_buf)
|
||||
|
||||
n: int
|
||||
for {
|
||||
va := args
|
||||
n = int(libc.vsnprintf(raw_data(rl_log_buf), len(rl_log_buf), text, va))
|
||||
if n < len(rl_log_buf) do break
|
||||
log.infof("Resizing raylib log buffer from %m to %m", len(rl_log_buf), len(rl_log_buf) * 2)
|
||||
rl_log_buf, _ = mem.resize_bytes(rl_log_buf, len(rl_log_buf) * 2)
|
||||
}
|
||||
|
||||
formatted := string(rl_log_buf[:n])
|
||||
log.log(level, formatted)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,28 +182,27 @@ pack_atlas_entries :: proc(
|
|||
atlas: ^rl.Image,
|
||||
offset_x: i32,
|
||||
offset_y: i32,
|
||||
allocator := context.allocator,
|
||||
) -> [dynamic]SpriteAtlasMetadata {
|
||||
assert(atlas.width != 0, "Atlas width shouldn't be 0!")
|
||||
assert(atlas.height != 0, "Atlas height shouldn't be 0!")
|
||||
|
||||
all_cell_images := make([dynamic]rl.Image, allocator) // it's fine to store it like this, rl.Image just stores a pointer to the data
|
||||
all_cell_images := make([dynamic]rl.Image) // it's fine to store it like this, rl.Image just stores a pointer to the data
|
||||
for &entry in entries {
|
||||
for cell in entry.cells {
|
||||
append(&all_cell_images, cell.img)
|
||||
}
|
||||
entry.layer_cell_count = make([dynamic]i32, len(entry.cells), allocator)
|
||||
entry.layer_cell_count = make([dynamic]i32, len(entry.cells))
|
||||
}
|
||||
|
||||
num_entries := len(all_cell_images)
|
||||
nodes := make([]stbrp.Node, num_entries, allocator)
|
||||
rects := make([]stbrp.Rect, num_entries, allocator)
|
||||
nodes := make([]stbrp.Node, num_entries)
|
||||
rects := make([]stbrp.Rect, num_entries)
|
||||
|
||||
EntryAndCell :: struct {
|
||||
entry: ^AtlasEntry,
|
||||
cell_of_entry: ^CellData,
|
||||
}
|
||||
rect_idx_to_entry_and_cell := make(map[int]EntryAndCell, 100, allocator)
|
||||
rect_idx_to_entry_and_cell := make(map[int]EntryAndCell, 100)
|
||||
|
||||
// Set the custom IDs
|
||||
cellIdx: int
|
||||
|
|
@ -241,15 +240,15 @@ pack_atlas_entries :: proc(
|
|||
src_rect := rl.Rectangle {
|
||||
x = 0,
|
||||
y = 0,
|
||||
width = auto_cast cell.img.width,
|
||||
height = auto_cast cell.img.height,
|
||||
width = f32(cell.img.width),
|
||||
height = f32(cell.img.height),
|
||||
}
|
||||
|
||||
dst_rect := rl.Rectangle {
|
||||
auto_cast rect.x + auto_cast offset_x,
|
||||
auto_cast rect.y + auto_cast offset_y,
|
||||
auto_cast cell.img.width,
|
||||
auto_cast cell.img.height,
|
||||
f32(i32(rect.x) + offset_x),
|
||||
f32(i32(rect.y) + offset_y),
|
||||
f32(cell.img.width),
|
||||
f32(cell.img.height),
|
||||
}
|
||||
|
||||
// note(stefan): drawing the sprite in the atlas in the packed coordinates
|
||||
|
|
@ -258,7 +257,7 @@ pack_atlas_entries :: proc(
|
|||
log.infof("Src rect: {0}\nDst rect:{1}", src_rect, dst_rect)
|
||||
}
|
||||
|
||||
metadata := make([dynamic]SpriteAtlasMetadata, allocator)
|
||||
metadata := make([dynamic]SpriteAtlasMetadata)
|
||||
for rect, rectIdx in rects {
|
||||
entry_and_cell := rect_idx_to_entry_and_cell[auto_cast rectIdx]
|
||||
entry := entry_and_cell.entry
|
||||
|
|
@ -267,10 +266,9 @@ pack_atlas_entries :: proc(
|
|||
cell_name: string
|
||||
if entry.layer_cell_count[cell.layer_index] > 1 {
|
||||
cell_name = fmt.aprintf(
|
||||
"{0}_%d",
|
||||
"{0}_{1}",
|
||||
entry.layer_names[cell.layer_index],
|
||||
cell.frame_index,
|
||||
allocator,
|
||||
)
|
||||
} else {
|
||||
cell_name = entry.layer_names[cell.layer_index]
|
||||
|
|
@ -278,8 +276,8 @@ pack_atlas_entries :: proc(
|
|||
cell_metadata := SpriteAtlasMetadata {
|
||||
name = cell_name,
|
||||
location = {
|
||||
auto_cast rect.x + auto_cast offset_x,
|
||||
auto_cast rect.y + auto_cast offset_y,
|
||||
i32(rect.x) + offset_x,
|
||||
i32(rect.y) + offset_y,
|
||||
},
|
||||
size = {auto_cast cell.img.width, auto_cast cell.img.height},
|
||||
}
|
||||
|
|
@ -308,7 +306,7 @@ odin_source_generator_metadata := SourceCodeGeneratorMetadata {
|
|||
},
|
||||
array_data = {
|
||||
name = "ATLAS_SPRITES",
|
||||
type = "[]AtlasRect",
|
||||
type = "[AtlasSprite]AtlasRect",
|
||||
begin_line = "%v := %v {{\n",
|
||||
entry_line = "\t.%v = {{ x = %v, y = %v, w = %v, h = %v }},\n",
|
||||
end_line = "}\n\n",
|
||||
|
|
@ -369,7 +367,7 @@ generate_odin_enums_and_atlas_offsets_file_sb :: proc(
|
|||
|
||||
// start offsets array
|
||||
// todo(stefan): the name of the array can be based on the output name?
|
||||
strings.write_string(&sb, "ATLAS_SPRITES := []AtlasRect {\n")
|
||||
strings.write_string(&sb, "ATLAS_SPRITES := [AtlasSprite]AtlasRect {\n")
|
||||
{
|
||||
entry: string
|
||||
for cell in metadata {
|
||||
|
|
|
|||
4
vendors/dialog/build.sh
vendored
4
vendors/dialog/build.sh
vendored
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
gcc ./libtinyfiledialogs/tinyfiledialogs.c -c -o libtinyfiledialogs.o
|
||||
|
||||
ar rcs libtinyfiledialogs.a libtinyfiledialogs.o
|
||||
|
||||
rm libtinyfiledialogs.o
|
||||
Loading…
Add table
Add a link
Reference in a new issue