541 lines
22 KiB
C
541 lines
22 KiB
C
|
|
#include "../global.h"
|
|
|
|
void export_arm_run_mesh(char *path, mesh_object_t_array_t *paint_objects) {
|
|
mesh_data_t_array_t *mesh_datas = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < paint_objects->length; ++i) {
|
|
mesh_object_t *p = paint_objects->buffer[i];
|
|
any_array_push(mesh_datas, p->data);
|
|
}
|
|
|
|
scene_t *raw = GC_ALLOC_INIT(scene_t, {.mesh_datas = mesh_datas});
|
|
buffer_t *b = util_encode_scene(raw);
|
|
|
|
if (!ends_with(path, ".arm")) {
|
|
path = string("%s.arm", path);
|
|
}
|
|
iron_file_save_bytes(path, b, b->length + 1);
|
|
}
|
|
|
|
void export_arm_export_node(ui_node_t *n, asset_t_array_t *assets) {
|
|
if (string_equals(n->type, "TEX_IMAGE")) {
|
|
i32 index = n->buttons->buffer[0]->default_value->buffer[0];
|
|
if (index > 9000) { // 9999 - Texture deleted
|
|
n->buttons->buffer[0]->data = u8_array_create_from_string("");
|
|
}
|
|
else {
|
|
n->buttons->buffer[0]->data = u8_array_create_from_string(base_combo_enum_texts(n->type)->buffer[index]);
|
|
}
|
|
if (assets != NULL) {
|
|
asset_t *asset = g_project->_->assets->buffer[index];
|
|
if (array_index_of(assets, asset) == -1) {
|
|
any_array_push(assets, asset);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
string_array_t *export_arm_assets_to_files(char *project_path, asset_t_array_t *assets) {
|
|
string_array_t *texture_files = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < assets->length; ++i) {
|
|
asset_t *a = assets->buffer[i];
|
|
#ifdef IRON_IOS
|
|
bool same_drive = false;
|
|
#else
|
|
bool same_drive = char_at(project_path, 0) == char_at(a->file, 0);
|
|
#endif
|
|
// Convert image path from absolute to relative
|
|
if (same_drive) {
|
|
any_array_push(texture_files, path_to_relative(project_path, a->file));
|
|
}
|
|
else {
|
|
any_array_push(texture_files, a->file);
|
|
}
|
|
}
|
|
return texture_files;
|
|
}
|
|
|
|
string_array_t *export_arm_meshes_to_files(char *project_path) {
|
|
string_array_t *mesh_files = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->mesh_assets->length; ++i) {
|
|
char *file = g_project->mesh_assets->buffer[i];
|
|
#ifdef IRON_IOS
|
|
bool same_drive = false;
|
|
#else
|
|
bool same_drive = char_at(project_path, 0) == char_at(file, 0);
|
|
#endif
|
|
// Convert mesh path from absolute to relative
|
|
if (same_drive) {
|
|
any_array_push(mesh_files, path_to_relative(project_path, file));
|
|
}
|
|
else {
|
|
any_array_push(mesh_files, file);
|
|
}
|
|
}
|
|
return mesh_files;
|
|
}
|
|
|
|
string_array_t *export_arm_fonts_to_files(char *project_path, slot_font_t_array_t *fonts) {
|
|
string_array_t *font_files = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 1; i < fonts->length; ++i) {
|
|
slot_font_t *f = fonts->buffer[i];
|
|
#ifdef IRON_IOS
|
|
bool same_drive = false;
|
|
#else
|
|
bool same_drive = char_at(project_path, 0) == char_at(f->file, 0);
|
|
#endif
|
|
// Convert font path from absolute to relative
|
|
if (same_drive) {
|
|
any_array_push(font_files, path_to_relative(project_path, f->file));
|
|
}
|
|
else {
|
|
any_array_push(font_files, f->file);
|
|
}
|
|
}
|
|
return font_files;
|
|
}
|
|
|
|
void export_arm_run_project() {
|
|
|
|
tab_timeline_prepare_save();
|
|
|
|
workflow_t _workflow = g_config->workflow;
|
|
g_config->workflow = WORKFLOW_PBR;
|
|
base_update_workflow();
|
|
|
|
ui_node_canvas_t_array_t *mnodes = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->_->materials->length; ++i) {
|
|
slot_material_t *m = g_project->_->materials->buffer[i];
|
|
ui_node_canvas_t *c = util_clone_canvas(m->canvas);
|
|
for (i32 i = 0; i < c->nodes->length; ++i) {
|
|
ui_node_t *n = c->nodes->buffer[i];
|
|
export_arm_export_node(n, NULL);
|
|
}
|
|
any_array_push(mnodes, c);
|
|
}
|
|
|
|
g_config->workflow = _workflow;
|
|
base_update_workflow();
|
|
|
|
ui_node_canvas_t_array_t *bnodes = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->_->brushes->length; ++i) {
|
|
slot_brush_t *b = g_project->_->brushes->buffer[i];
|
|
ui_node_canvas_t *c = util_clone_canvas(b->canvas);
|
|
for (i32 i = 0; i < c->nodes->length; ++i) {
|
|
ui_node_t *n = c->nodes->buffer[i];
|
|
export_arm_export_node(n, NULL);
|
|
}
|
|
any_array_push(bnodes, c);
|
|
}
|
|
|
|
ui_node_canvas_t_array_t *mgroups = NULL;
|
|
if (g_project->_->material_groups->length > 0) {
|
|
mgroups = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->_->material_groups->length; ++i) {
|
|
node_group_t *g = g_project->_->material_groups->buffer[i];
|
|
ui_node_canvas_t *c = util_clone_canvas(g->canvas);
|
|
for (i32 i = 0; i < c->nodes->length; ++i) {
|
|
ui_node_t *n = c->nodes->buffer[i];
|
|
export_arm_export_node(n, NULL);
|
|
}
|
|
any_array_push(mgroups, c);
|
|
}
|
|
}
|
|
|
|
material_data2_t_array_t *mdata2 = NULL;
|
|
if (g_project->_->materials->length > 0) {
|
|
mdata2 = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->_->materials->length; ++i) {
|
|
slot_material_t *m = g_project->_->materials->buffer[i];
|
|
material_data2_t *d = GC_ALLOC_INIT(material_data2_t, {
|
|
.paint_base = m->paint_base,
|
|
.paint_opac = m->paint_opac,
|
|
.paint_occ = m->paint_occ,
|
|
.paint_rough = m->paint_rough,
|
|
.paint_met = m->paint_met,
|
|
.paint_nor = m->paint_nor,
|
|
.paint_height = m->paint_height,
|
|
.paint_emis = m->paint_emis,
|
|
.paint_subs = m->paint_subs,
|
|
.opac_mode = m->paint_opac_mode,
|
|
});
|
|
any_array_push(mdata2, d);
|
|
}
|
|
}
|
|
|
|
mesh_data_t_array_t *md = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
|
mesh_object_t *p = g_project->_->paint_objects->buffer[i];
|
|
any_array_push(md, p->data);
|
|
}
|
|
|
|
string_array_t *texture_files = export_arm_assets_to_files(g_project->_->filepath, g_project->_->assets);
|
|
|
|
string_array_t *font_files = export_arm_fonts_to_files(g_project->_->filepath, g_project->_->fonts);
|
|
string_array_t *mesh_files = export_arm_meshes_to_files(g_project->_->filepath);
|
|
|
|
i32 bits_pos = base_bits_handle->i;
|
|
i32 bpp = bits_pos == TEXTURE_BITS_BITS8 ? 8 : bits_pos == TEXTURE_BITS_BITS16 ? 16 : 32;
|
|
|
|
layer_data_t_array_t *ld = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->_->layers->length; ++i) {
|
|
slot_layer_t *l = g_project->_->layers->buffer[i];
|
|
layer_data_t *d =
|
|
GC_ALLOC_INIT(layer_data_t, {.name = l->name,
|
|
.res = l->texpaint != NULL ? l->texpaint->width : g_project->_->layers->buffer[0]->texpaint->width,
|
|
.bpp = bpp,
|
|
.texpaint = l->texpaint != NULL ? lz4_encode(gpu_get_texture_pixels(l->texpaint)) : NULL,
|
|
.uv_scale = l->scale,
|
|
.uv_rot = l->angle,
|
|
.uv_type = l->uv_type,
|
|
.uv_map = l->uv_map,
|
|
.decal_mat = l->uv_type == UV_TYPE_PROJECT ? mat4_to_f32_array(l->decal_mat) : NULL,
|
|
.opacity_mask = l->mask_opacity,
|
|
.fill_material = l->fill_material != NULL ? array_index_of(g_project->_->materials, l->fill_material) : -1,
|
|
.object_mask = l->object_mask,
|
|
.blending = l->blending,
|
|
.parent = l->parent != NULL ? array_index_of(g_project->_->layers, l->parent) : -1,
|
|
.visible = l->visible,
|
|
.texpaint_nor = l->texpaint_nor != NULL ? lz4_encode(gpu_get_texture_pixels(l->texpaint_nor)) : NULL,
|
|
.texpaint_pack = l->texpaint_pack != NULL ? lz4_encode(gpu_get_texture_pixels(l->texpaint_pack)) : NULL,
|
|
.paint_base = l->paint_base,
|
|
.paint_opac = l->paint_opac,
|
|
.paint_occ = l->paint_occ,
|
|
.paint_rough = l->paint_rough,
|
|
.paint_met = l->paint_met,
|
|
.paint_nor = l->paint_nor,
|
|
.paint_nor_blend = l->paint_nor_blend,
|
|
.paint_height = l->paint_height,
|
|
.paint_height_blend = l->paint_height_blend,
|
|
.paint_emis = l->paint_emis,
|
|
.paint_subs = l->paint_subs,
|
|
.path_points = l->path_points,
|
|
.path_points_world = l->path_points_world,
|
|
.path_points_camera = l->path_points_camera,
|
|
.path_points_parent = l->path_points_parent,
|
|
.path_tool = l->path_tool,
|
|
.path_curved = l->path_curved,
|
|
.path_material = l->path_material != NULL ? array_index_of(g_project->_->materials, l->path_material) : -1});
|
|
any_array_push(ld, d);
|
|
}
|
|
|
|
packed_asset_t_array_t *packed_assets = (g_project->packed_assets == NULL || g_project->packed_assets->length == 0) ? NULL : g_project->packed_assets;
|
|
#ifdef IRON_IOS
|
|
bool same_drive = false;
|
|
#else
|
|
bool same_drive = g_project->envmap != NULL ? char_at(g_project->_->filepath, 0) == char_at(g_project->envmap, 0) : true;
|
|
#endif
|
|
|
|
g_project->version = string_copy(manifest_version_project);
|
|
g_project->material_groups = mgroups;
|
|
g_project->material_datas = mdata2;
|
|
g_project->assets = texture_files;
|
|
g_project->packed_assets = packed_assets;
|
|
g_project->swatches = g_project->swatches;
|
|
g_project->envmap = g_project->envmap != NULL ? (same_drive ? path_to_relative(g_project->_->filepath, g_project->envmap) : g_project->envmap) : NULL;
|
|
g_project->envmap_strength = scene_world->strength;
|
|
g_project->envmap_angle = g_context->envmap_angle;
|
|
g_project->envmap_blur = g_context->show_envmap_blur;
|
|
g_project->camera_world = mat4_to_f32_array(scene_camera->base->transform->local);
|
|
g_project->camera_origin = vec3_to_f32_array(camera_origins[0]);
|
|
g_project->camera_fov = scene_camera->data->fov;
|
|
|
|
// g_project.mesh_datas = md; // TODO: fix GC ref
|
|
if (g_project->mesh_datas == NULL) {
|
|
g_project->mesh_datas = md;
|
|
}
|
|
else {
|
|
g_project->mesh_datas->length = 0;
|
|
for (i32 i = 0; i < md->length; ++i) {
|
|
any_array_push(g_project->mesh_datas, md->buffer[i]);
|
|
}
|
|
}
|
|
|
|
f32_array_t_array_t *mesh_transforms = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
|
mesh_object_t *p = g_project->_->paint_objects->buffer[i];
|
|
f32_array_t *ar = f32_array_create_from_raw(p->base->transform->local.m, 16);
|
|
any_array_push(mesh_transforms, ar);
|
|
}
|
|
g_project->mesh_transforms = mesh_transforms;
|
|
|
|
if (g_project->mesh_materials != NULL) {
|
|
g_project->mesh_materials = i32_array_create(g_project->_->paint_objects->length);
|
|
for (i32 i = 0; i < g_project->mesh_materials->length; ++i) {
|
|
g_project->mesh_materials->buffer[i] = tab_meshes_get_override(g_project->_->paint_objects->buffer[i]);
|
|
}
|
|
}
|
|
|
|
if (g_project->mesh_parents != NULL) {
|
|
g_project->mesh_parents = i32_array_create(g_project->_->paint_objects->length);
|
|
for (i32 i = 0; i < g_project->mesh_parents->length; ++i) {
|
|
object_t *parent = g_project->_->paint_objects->buffer[i]->base->parent;
|
|
g_project->mesh_parents->buffer[i] = -1; // No parent
|
|
if (parent != NULL && parent != _scene_scene_parent) {
|
|
for (i32 j = 0; j < g_project->mesh_parents->length; ++j) {
|
|
if (g_project->_->paint_objects->buffer[j]->base == parent) {
|
|
g_project->mesh_parents->buffer[i] = j;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
g_project->material_nodes = mnodes;
|
|
g_project->brush_nodes = bnodes;
|
|
g_project->layer_datas = ld;
|
|
g_project->font_assets = font_files;
|
|
g_project->mesh_assets = mesh_files;
|
|
|
|
tab_timeline_export(g_project);
|
|
|
|
#ifdef IRON_BGRA
|
|
g_project->is_bgra = true;
|
|
#else
|
|
g_project->is_bgra = false;
|
|
#endif
|
|
|
|
#if defined(IRON_ANDROID) || defined(IRON_IOS)
|
|
render_target_t *rt = any_map_get(render_path_render_targets, "buf");
|
|
gpu_texture_t *tex = rt->_image;
|
|
gpu_texture_t *mesh_icon = gpu_create_render_target(256, 256, GPU_TEXTURE_FORMAT_RGBA32);
|
|
f32 r = sys_w() / (float)sys_h();
|
|
draw_begin(mesh_icon, false, 0);
|
|
draw_scaled_image(tex, -(256 * r - 256) / 2.0, 0, 256 * r, 256);
|
|
draw_end();
|
|
|
|
buffer_t *mesh_icon_pixels = gpu_get_texture_pixels(mesh_icon);
|
|
u8_array_t *u8a = mesh_icon_pixels;
|
|
for (i32 i = 0; i < 256 * 256 * 4; ++i) {
|
|
u8a->buffer[i] = math_floor(math_pow(u8a->buffer[i] / 255.0, 1.0 / 2.2) * 255);
|
|
}
|
|
iron_write_png(string("%s_icon.png", substring(g_project->_->filepath, 0, string_length(g_project->_->filepath) - 4)), mesh_icon_pixels, 256, 256, 0);
|
|
gpu_delete_texture(mesh_icon);
|
|
#endif
|
|
|
|
if (g_context->pack_assets_on_save) { // Pack textures
|
|
export_arm_pack_assets(g_project, g_project->_->assets);
|
|
}
|
|
|
|
buffer_t *buffer = util_encode_project(g_project);
|
|
iron_file_save_bytes(g_project->_->filepath, buffer, buffer->length + 1);
|
|
|
|
// Save to recent
|
|
#ifdef IRON_IOS
|
|
char *recent_path = substring(g_project->_->filepath, string_last_index_of(g_project->_->filepath, "/") + 1, string_length(g_project->_->filepath));
|
|
#else
|
|
char *recent_path = g_project->_->filepath;
|
|
#endif
|
|
|
|
#ifdef IRON_WINDOWS
|
|
recent_path = string_copy(string_replace_all(recent_path, "\\", "/"));
|
|
#endif
|
|
string_array_t *recent = g_config->recent_projects;
|
|
string_array_remove(recent, recent_path);
|
|
array_insert(recent, 0, recent_path);
|
|
config_save();
|
|
|
|
tab_timeline_finish_save();
|
|
|
|
console_info(tr("Project saved"));
|
|
}
|
|
|
|
packed_asset_t_array_t *export_arm_get_packed_assets(char *project_path, string_array_t *texture_files) {
|
|
packed_asset_t_array_t *packed_assets = NULL;
|
|
if (g_project->packed_assets != NULL) {
|
|
for (i32 i = 0; i < g_project->packed_assets->length; ++i) {
|
|
packed_asset_t *pa = g_project->packed_assets->buffer[i];
|
|
#ifdef IRON_IOS
|
|
bool same_drive = false;
|
|
#else
|
|
bool same_drive = char_at(project_path, 0) == char_at(pa->name, 0);
|
|
#endif
|
|
// Convert path from absolute to relative
|
|
pa->name = same_drive ? path_to_relative(project_path, pa->name) : pa->name;
|
|
for (i32 i = 0; i < texture_files->length; ++i) {
|
|
char *tf = texture_files->buffer[i];
|
|
if (string_equals(pa->name, tf)) {
|
|
if (packed_assets == NULL) {
|
|
packed_assets = any_array_create_from_raw((void *[]){}, 0);
|
|
}
|
|
any_array_push(packed_assets, pa);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return packed_assets;
|
|
}
|
|
|
|
void export_arm_run_material(char *path) {
|
|
if (!ends_with(path, ".arm")) {
|
|
path = string("%s.arm", path);
|
|
}
|
|
ui_node_canvas_t_array_t *mnodes = any_array_create_from_raw((void *[]){}, 0);
|
|
ui_node_canvas_t_array_t *mgroups = NULL;
|
|
slot_material_t *m = g_context->material;
|
|
ui_node_canvas_t *c = util_clone_canvas(m->canvas);
|
|
asset_t_array_t *assets = any_array_create_from_raw((void *[]){}, 0);
|
|
if (ui_nodes_has_group(c)) {
|
|
mgroups = any_array_create_from_raw((void *[]){}, 0);
|
|
ui_nodes_traverse_group(mgroups, c);
|
|
for (i32 i = 0; i < mgroups->length; ++i) {
|
|
ui_node_canvas_t *gc = mgroups->buffer[i];
|
|
for (i32 i = 0; i < gc->nodes->length; ++i) {
|
|
ui_node_t *n = gc->nodes->buffer[i];
|
|
export_arm_export_node(n, assets);
|
|
}
|
|
}
|
|
}
|
|
for (i32 i = 0; i < c->nodes->length; ++i) {
|
|
ui_node_t *n = c->nodes->buffer[i];
|
|
export_arm_export_node(n, assets);
|
|
}
|
|
any_array_push(mnodes, c);
|
|
|
|
string_array_t *texture_files = export_arm_assets_to_files(path, assets);
|
|
packed_asset_t_array_t *packed_assets = NULL;
|
|
if (!g_context->pack_assets_on_export) {
|
|
packed_assets = export_arm_get_packed_assets(path, texture_files);
|
|
}
|
|
|
|
#ifdef IRON_BGRA
|
|
buffer_t *buf = lz4_encode(buffer_bgra64_swap(gpu_get_texture_pixels(m->image)));
|
|
#else
|
|
buffer_t *buf = lz4_encode(gpu_get_texture_pixels(m->image));
|
|
#endif
|
|
buffer_t_array_t *micons = any_array_create_from_raw(
|
|
(void *[]){
|
|
buf,
|
|
},
|
|
1);
|
|
|
|
material_data2_t_array_t *mdata2 = any_array_create_from_raw((void *[]){}, 0);
|
|
material_data2_t *md2 = GC_ALLOC_INIT(material_data2_t, {
|
|
.paint_base = m->paint_base,
|
|
.paint_opac = m->paint_opac,
|
|
.paint_occ = m->paint_occ,
|
|
.paint_rough = m->paint_rough,
|
|
.paint_met = m->paint_met,
|
|
.paint_nor = m->paint_nor,
|
|
.paint_height = m->paint_height,
|
|
.paint_emis = m->paint_emis,
|
|
.paint_subs = m->paint_subs,
|
|
.opac_mode = m->paint_opac_mode,
|
|
});
|
|
any_array_push(mdata2, md2);
|
|
|
|
project_t *raw = GC_ALLOC_INIT(project_t, {.version = manifest_version_project,
|
|
.material_nodes = mnodes,
|
|
.material_groups = mgroups,
|
|
.material_icons = micons,
|
|
.material_datas = mdata2,
|
|
.assets = texture_files,
|
|
.packed_assets = packed_assets});
|
|
|
|
if (g_context->write_icon_on_export) { // Separate icon files
|
|
buffer_t *buf = buffer_half_to_u8(gpu_get_texture_pixels(m->image));
|
|
#ifdef IRON_BGRA
|
|
buf = buffer_bgra_swap(buf);
|
|
#endif
|
|
iron_write_png(string("%s_icon.png", substring(path, 0, string_length(path) - 4)), buf, m->image->width, m->image->height, 0);
|
|
iron_write_jpg(string("%s_icon.jpg", substring(path, 0, string_length(path) - 4)), buf, m->image->width, m->image->height, 0, 50);
|
|
}
|
|
|
|
if (g_context->pack_assets_on_export) { // Pack textures
|
|
export_arm_pack_assets(raw, assets);
|
|
}
|
|
|
|
buffer_t *buffer = util_encode_project(raw);
|
|
iron_file_save_bytes(path, buffer, buffer->length + 1);
|
|
}
|
|
|
|
void export_arm_run_brush(char *path) {
|
|
if (!ends_with(path, ".arm")) {
|
|
path = string("%s.arm", path);
|
|
}
|
|
ui_node_canvas_t_array_t *bnodes = any_array_create_from_raw((void *[]){}, 0);
|
|
slot_brush_t *b = g_context->brush;
|
|
ui_node_canvas_t *c = util_clone_canvas(b->canvas);
|
|
asset_t_array_t *assets = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < c->nodes->length; ++i) {
|
|
ui_node_t *n = c->nodes->buffer[i];
|
|
export_arm_export_node(n, assets);
|
|
}
|
|
any_array_push(bnodes, c);
|
|
|
|
string_array_t *texture_files = export_arm_assets_to_files(path, assets);
|
|
packed_asset_t_array_t *packed_assets = NULL;
|
|
if (!g_context->pack_assets_on_export) {
|
|
packed_assets = export_arm_get_packed_assets(path, texture_files);
|
|
}
|
|
|
|
#ifdef IRON_BGRA
|
|
buffer_t *buf = lz4_encode(buffer_bgra_swap(gpu_get_texture_pixels(b->image)));
|
|
#else
|
|
buffer_t *buf = lz4_encode(gpu_get_texture_pixels(b->image));
|
|
#endif
|
|
buffer_t_array_t *bicons = any_array_create_from_raw(
|
|
(void *[]){
|
|
buf,
|
|
},
|
|
1);
|
|
|
|
project_t *raw = GC_ALLOC_INIT(
|
|
project_t,
|
|
{.version = manifest_version_project, .brush_nodes = bnodes, .brush_icons = bicons, .assets = texture_files, .packed_assets = packed_assets});
|
|
|
|
if (g_context->write_icon_on_export) { // Separate icon files
|
|
buffer_t *buf = gpu_get_texture_pixels(b->image);
|
|
#ifdef IRON_BGRA
|
|
buf = buffer_bgra_swap(buf);
|
|
#endif
|
|
iron_write_png(string("%s_icon.png", substring(path, 0, string_length(path) - 4)), buf, b->image->width, b->image->height, 0);
|
|
iron_write_jpg(string("%s_icon.jpg", substring(path, 0, string_length(path) - 4)), buf, b->image->width, b->image->height, 0, 50);
|
|
}
|
|
|
|
if (g_context->pack_assets_on_export) { // Pack textures
|
|
export_arm_pack_assets(raw, assets);
|
|
}
|
|
|
|
buffer_t *buffer = util_encode_project(raw);
|
|
iron_file_save_bytes(path, buffer, buffer->length + 1);
|
|
}
|
|
|
|
void export_arm_pack_assets(project_t *raw, asset_t_array_t *assets) {
|
|
if (raw->packed_assets == NULL) {
|
|
raw->packed_assets = any_array_create_from_raw((void *[]){}, 0);
|
|
}
|
|
gpu_texture_t_array_t *temp_images = any_array_create_from_raw((void *[]){}, 0);
|
|
for (i32 i = 0; i < assets->length; ++i) {
|
|
if (!project_packed_asset_exists(raw->packed_assets, assets->buffer[i]->file)) {
|
|
gpu_texture_t *image = project_get_image(assets->buffer[i]);
|
|
gpu_texture_t *temp = gpu_create_render_target(image->width, image->height, GPU_TEXTURE_FORMAT_RGBA32);
|
|
draw_begin(temp, false, 0);
|
|
draw_image(image, 0, 0);
|
|
draw_end();
|
|
any_array_push(temp_images, temp);
|
|
packed_asset_t *pa = GC_ALLOC_INIT(packed_asset_t, {.name = assets->buffer[i]->file,
|
|
.bytes = ends_with(assets->buffer[i]->file, ".jpg")
|
|
? iron_encode_jpg(gpu_get_texture_pixels(temp), temp->width, temp->height, 0, 80)
|
|
: iron_encode_png(gpu_get_texture_pixels(temp), temp->width, temp->height, 0)});
|
|
any_array_push(raw->packed_assets, pa);
|
|
}
|
|
}
|
|
|
|
for (i32 i = 0; i < temp_images->length; ++i) {
|
|
gpu_texture_t *image = temp_images->buffer[i];
|
|
gpu_delete_texture(image);
|
|
}
|
|
}
|
|
|
|
void export_arm_run_swatches(char *path) {
|
|
if (!ends_with(path, ".arm")) {
|
|
path = string("%s.arm", path);
|
|
}
|
|
project_t *raw = GC_ALLOC_INIT(project_t, {.version = manifest_version_project, .swatches = g_project->swatches});
|
|
buffer_t *buffer = util_encode_project(raw);
|
|
iron_file_save_bytes(path, buffer, buffer->length + 1);
|
|
}
|