cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

makecom.c (4192B)


      1// This is free and unencumbered software released into the public domain.
      2// For more information, please refer to <https://unlicense.org>
      3// bbbbbr 2022
      4
      5#include <stdio.h>
      6#include <string.h>
      7#include <stdlib.h>
      8#include <stdbool.h>
      9#include <stdint.h>
     10#include <ctype.h>
     11
     12#include "path_ops.h"
     13#include "common.h"
     14#include "files.h"
     15#include "noi_file.h"
     16#include "bin_to_com.h"
     17
     18#define EXT_NOI "noi"
     19
     20char filename_in_bin[MAX_STR_LEN] = "";
     21char filename_in_noi[MAX_STR_LEN] = "";
     22char filename_out_com[MAX_STR_LEN] = "";
     23char filename_banks_base[MAX_STR_LEN] = "";
     24char filename_overlay[COM_OVERLAY_NAME_LEN] = "";
     25
     26uint8_t * p_rom_buf_in  = NULL;
     27size_t    rom_buf_in_len = 0;
     28
     29static void str_to_upper(char * str);
     30static void filenames_out_prepare(void);
     31static void display_help(void);
     32static int handle_args(int argc, char * argv[]);
     33void cleanup(void);
     34
     35
     36static void str_to_upper(char * str) {
     37    while (*str) {
     38        *str = toupper(*str);
     39        str++;
     40    }
     41}
     42
     43
     44
     45// Generate names for the exported bank/overlay files
     46// based on the output COM filename and path
     47static void filenames_out_prepare(void) {
     48
     49    char str_banks_name[MAX_STR_LEN];
     50    char str_path_only[MAX_STR_LEN];
     51
     52    snprintf(str_banks_name,  sizeof(str_banks_name), "%s", filename_out_com);
     53
     54    if (!get_path_without_filename(filename_out_com, str_path_only, sizeof(str_path_only))) {
     55        printf("makecom: Error: source path %s exceeds max length\n", filename_out_com);
     56        exit;
     57    }
     58
     59    // Convert filename to uppercase and remove extension
     60    str_to_upper(str_banks_name);
     61    filename_remove_extension(str_banks_name);
     62
     63    // Then truncate it to 8 characters with no padding for bank filenames
     64    int ret = snprintf(filename_banks_base, sizeof(filename_banks_base), "%s%.8s", str_path_only, get_filename_from_path(str_banks_name));
     65    if (ret < 0) printf("makecom: Warning, banks output path truncated\n");
     66    // Then with trailing space char padding for the overlay filename patch
     67    snprintf(filename_overlay, sizeof(filename_overlay), "%-8.8s", get_filename_from_path(str_banks_name));
     68}
     69
     70
     71static void display_help(void) {
     72
     73    fprintf(stdout,
     74       "makecom image.rom image.noi output.com\n"
     75       "Use: convert a binary .rom file to .msxdos com format.\n"
     76       );
     77}
     78
     79
     80int handle_args(int argc, char * argv[]) {
     81
     82    if (argc == 3) {
     83        // Copy input and output filenames from arguments
     84        snprintf(filename_in_bin,  sizeof(filename_in_bin),  "%s", argv[1]);
     85        snprintf(filename_out_com, sizeof(filename_out_com), "%s", argv[2]);
     86        // Generate .noi file name from input .bin file name
     87        snprintf(filename_in_noi,  sizeof(filename_in_noi),  "%s", argv[1]);
     88        filename_replace_extension(filename_in_noi, EXT_NOI, MAX_STR_LEN);
     89    } else if (argc == 4) {
     90        // Copy input and output filenames from arguments
     91        snprintf(filename_in_bin,  sizeof(filename_in_bin),  "%s", argv[1]);
     92        snprintf(filename_in_noi,  sizeof(filename_in_noi),  "%s", argv[2]);
     93        snprintf(filename_out_com, sizeof(filename_out_com), "%s", argv[3]);
     94    } else {
     95        display_help();
     96        return false;
     97    }
     98
     99    filenames_out_prepare();
    100
    101
    102    // printf("bin: %s\n",filename_in_bin);
    103    // printf("noi: %s\n",filename_in_noi);
    104    // printf("com: %s\n",filename_out_com);
    105
    106    // printf("banks base: _%s_\n",filename_banks_base);
    107    // printf("overlay   : _%s_\n",filename_overlay);
    108
    109
    110    return true;
    111}
    112
    113
    114// Registered as atexit() handler
    115// Free resources during normal shutdown or from a call to exit()
    116void cleanup(void) {
    117
    118    banks_cleanup();
    119    noi_cleanup();
    120
    121    if (p_rom_buf_in != NULL) {
    122        free(p_rom_buf_in);
    123        p_rom_buf_in = NULL;
    124    }
    125}
    126
    127
    128int main( int argc, char *argv[] )  {
    129
    130    // Exit with failure by default
    131    int ret = EXIT_FAILURE;
    132
    133    // Register cleanup with exit handler
    134    atexit(cleanup);
    135
    136    if (handle_args(argc, argv)) {
    137
    138        p_rom_buf_in = file_read_into_buffer(filename_in_bin, &rom_buf_in_len);
    139
    140        if (p_rom_buf_in)
    141            if (noi_file_load_symbols(filename_in_noi))
    142                ret = bin2com();
    143    }
    144    cleanup();
    145
    146    return ret; // Exit with failure by default
    147}