2D_Engine_C/assets/asset_builder/main.c

186 lines
6.2 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "object.h"
#include "utils.h"
#include "errors.h"
typedef enum build_function_t {
BUILD_OBJECT,
BUILD_ASSET_FILE
} build_function_t;
void print_usage(void)
{
puts("\033[33musage\033[m:");
puts("\tasset_builder output_object_file -c input_file");
puts("\tasset_builder output_asset_file input_object_file [input_object_file2 ...]");
}
int main(int argc, char *argv[])
{
// Parse args
if(argc < 3)
{
print_usage();
return EXIT_FAILURE;
}
const build_function_t build_function = strcmp(argv[2], "-c") ? BUILD_ASSET_FILE : BUILD_OBJECT;
const char *output_file_path = argv[1];
FILE *output_file = fopen(output_file_path, "wb");
if(!output_file)
{
error_printf("Failed to open output file : %d", errno);
return EXIT_FAILURE;
}
if(build_function == BUILD_OBJECT)
{
if(argc != 4)
{
print_usage();
return EXIT_FAILURE;
}
const char *input_file_path = argv[3];
if(build_object(input_file_path, output_file)) goto_failure;
}
else if(build_function == BUILD_ASSET_FILE)
{
uint32_t header_size = 0;
const int nb_input_object_files = argc - 2;
if(file_write(&nb_input_object_files, sizeof(nb_input_object_files), 1, output_file)) goto_failure;
header_size += sizeof(nb_input_object_files);
FILE *input_object_files[nb_input_object_files];
uint32_t input_object_files_sizes[nb_input_object_files];
uint32_t input_object_files_offsets[nb_input_object_files];
for(int i = 0; i < nb_input_object_files; i++)
{
const char *input_object_file_path = argv[i + 2];
input_object_files[i] = fopen(input_object_file_path, "rb");
if(!input_object_files[i])
{
error_printf("Failed to open input object file : %d", errno);
for(; i >= 0; i--)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
goto_failure;
}
if(file_read(&input_object_files_sizes[i], sizeof(*input_object_files_sizes), 1, input_object_files[i]))
{
for(; i >= 0; i--)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
goto_failure;
}
const char *input_object_file_slash = strrchr(input_object_file_path, '/');
const char *input_object_file_name = input_object_file_slash ? input_object_file_slash + 1 : input_object_file_path;
const char *input_object_file_ext = strchr(input_object_file_path, '.');
uint32_t input_object_file_base_name_length = strlen(input_object_file_name) - strlen(input_object_file_ext) + 1;
header_size += input_object_file_base_name_length * sizeof(*input_object_file_name);
header_size += sizeof(*input_object_files_offsets);
}
input_object_files_offsets[0] = header_size;
for(int i = 0; i < nb_input_object_files; i++)
{
if(i) input_object_files_offsets[i] = input_object_files_offsets[i - 1] + input_object_files_sizes[i - 1];
char *input_object_file_path = argv[i + 2];
const char *input_object_file_slash = strrchr(input_object_file_path, '/');
const char *input_object_file_name = input_object_file_slash ? input_object_file_slash + 1 : input_object_file_path;
char *input_object_file_ext = strchr(input_object_file_path, '.');
input_object_file_ext[0] = '\00';
uint32_t input_object_file_base_name_length = strlen(input_object_file_name) - strlen(input_object_file_ext) + 1;
if(file_write(input_object_file_name, sizeof(*input_object_file_name), input_object_file_base_name_length, output_file))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
goto_failure;
}
if(file_write(&input_object_files_offsets[i], sizeof(*input_object_files_offsets), 1, output_file))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
goto_failure;
}
}
for(int i = 0; i < nb_input_object_files; i++)
{
char buffer[input_object_files_sizes[i]];
if(file_read(buffer, sizeof(*buffer), input_object_files_sizes[i], input_object_files[i]))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
goto_failure;
}
if(file_write(buffer, sizeof(*buffer), input_object_files_sizes[i], output_file))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
goto_failure;
}
}
for(int i = 0; i < nb_input_object_files; i++)
{
if(fclose(input_object_files[i]))
{
error_printf("Failed to close input object file : %d", errno);
for(i++; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
goto_failure;
}
}
}
if(fclose(output_file))
{
error_printf("Failed to close output file : %d", errno);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
failure:
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return EXIT_FAILURE;
}