From b70316eaab76100aa8e392910a04017976087f15 Mon Sep 17 00:00:00 2001 From: ds-sloth <72112344+ds-sloth@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:46:40 -0400 Subject: [PATCH] Add library build --- CMakeLists.txt | 13 +++-- include/spc2it.h | 18 ++++++ src/emu.c | 4 +- src/emu.h | 2 +- src/it.c | 35 +++++------- src/it.h | 3 +- src/lib.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.h | 12 ++++ src/main.c | 128 ++++-------------------------------------- src/spc2ittypes.h | 2 +- 10 files changed, 207 insertions(+), 148 deletions(-) create mode 100644 include/spc2it.h create mode 100644 src/lib.c create mode 100644 src/lib.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 98f62f2..4dd34a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,9 @@ project(spc2it) set(spc2it_sources src/emu.c src/it.c - src/main.c src/sound.c src/spc700.c + src/lib.c src/emu.h src/it.h @@ -15,7 +15,12 @@ set(spc2it_sources src/spc2ittypes.h ) -add_executable(spc2it ${spc2it_sources}) -target_include_directories(spc2it PRIVATE src) +add_library(libspc2it STATIC ${spc2it_sources}) +target_include_directories(libspc2it PRIVATE src) +target_include_directories(libspc2it PUBLIC include) +target_link_libraries(libspc2it m) + +add_executable(spc2it_cli src/main.c) +target_link_libraries(spc2it_cli libspc2it) +set_target_properties(spc2it_cli PROPERTIES OUTPUT_NAME "spc2it") -target_link_libraries(spc2it m) diff --git a/include/spc2it.h b/include/spc2it.h new file mode 100644 index 0000000..557e6f1 --- /dev/null +++ b/include/spc2it.h @@ -0,0 +1,18 @@ +/**************************************************** +*Part of SPC2IT, read readme.md for more information* +****************************************************/ + +#ifndef SPC2IT_H +#define SPC2IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +int spc2it_convert(const char* src, const char* dest); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/emu.c b/src/emu.c index 46928c4..f391cd2 100644 --- a/src/emu.c +++ b/src/emu.c @@ -28,7 +28,7 @@ void (*SPC_Write_DSP_Hook)(u8); // function pointer s32 SPCtime; SPCFileInformation SPCInfo; -static s32 LoadZState(char *fn) +static s32 LoadZState(const char *fn) { SPCFile *sFile = (SPCFile *)calloc(1, sizeof(SPCFile)); if (sFile == NULL) @@ -95,7 +95,7 @@ static s32 LoadZState(char *fn) // PUBLIC (non-static) functions -s32 SPCInit(char *fn) +s32 SPCInit(const char *fn) { Reset_SPC(); if (LoadZState(fn)) diff --git a/src/emu.h b/src/emu.h index 8e06b83..17d268f 100644 --- a/src/emu.h +++ b/src/emu.h @@ -17,7 +17,7 @@ extern void (*SPC_Write_DSP_Hook)(u8); #define SPCUpdateRate 100 -s32 SPCInit(char *); +s32 SPCInit(const char *); void SPCAddWriteDSPCallback(void (*ToAddCallback)(u8)); #endif diff --git a/src/it.c b/src/it.c index ace8c47..dd0b126 100644 --- a/src/it.c +++ b/src/it.c @@ -346,15 +346,12 @@ s32 ITUpdate() // Dumps pattern buffers to file return 0; } -s32 ITWrite(char *fn) // Write the final IT file +s32 ITWrite(const char *fn) // Write the final IT file { - s32 ret = 0; - if (fn == NULL) { // printf("Error: no IT filename\n"); - ret = 1; - goto cleanup; + return 1; } FILE *f; @@ -365,8 +362,7 @@ s32 ITWrite(char *fn) // Write the final IT file if (pInfo == NULL) { // printf("Error: could not allocate memory for ITPatternInfo struct\n"); - ret = 1; - goto cleanup; + return 1; } // START IT CLEANUP @@ -390,10 +386,7 @@ s32 ITWrite(char *fn) // Write the final IT file ITpattlen[ITcurbuf++] = ITbufpos; if (ITUpdate()) // Save the changes we just made - { - ret = 1; - goto cleanup; - } + return 1; // END IT CLEANUP ITFileHeader *fHeader; @@ -401,8 +394,7 @@ s32 ITWrite(char *fn) // Write the final IT file if (fHeader == NULL) { // printf("Error: could not allocate memory for ITFileHeader struct\n"); - ret = 1; - goto cleanup; + return 1; } memcpy(fHeader->magic, "IMPM", 4); @@ -436,8 +428,7 @@ s32 ITWrite(char *fn) // Write the final IT file { // printf("Error: could not open IT file\n"); free(fHeader); - ret = 1; - goto cleanup; + return 1; } // header @@ -471,9 +462,8 @@ s32 ITWrite(char *fn) // Write the final IT file { if (ITSSave(ITSamples[i], f)) { - ret = 1; fclose(f); - goto cleanup; + return 1; } } @@ -483,15 +473,19 @@ s32 ITWrite(char *fn) // Write the final IT file // close file fclose(f); -cleanup: + return 0; +} + +void ITCleanup() +{ // generic cleanup that must occur in any case - for (i = 0; i < NUM_PATT_BUFS; i++) + for (int i = 0; i < NUM_PATT_BUFS; i++) { free(ITpattbuf[i]); ITpattbuf[i] = NULL; } - for (i = 0; i < numsamps; i++) + for (int i = 0; i < IT_SAMPLE_MAX; i++) { if (!ITSamples[i]) continue; @@ -504,7 +498,6 @@ s32 ITWrite(char *fn) // Write the final IT file free(ITPatterns); ITPatterns = NULL; - return ret; } int ITMix() diff --git a/src/it.h b/src/it.h index 33da123..e9a6961 100644 --- a/src/it.h +++ b/src/it.h @@ -11,7 +11,8 @@ s32 ITStart(s32); // Opens temp file, inits writing s32 ITUpdate(); // Dumps pattern buffers to file -s32 ITWrite(char *fn); // Stops recording and writes IT file from temp data +s32 ITWrite(const char *fn); // Stops recording and writes IT file from temp data +void ITCleanup(); // clears IT temp data int ITMix(); // Macros diff --git a/src/lib.c b/src/lib.c new file mode 100644 index 0000000..f87f063 --- /dev/null +++ b/src/lib.c @@ -0,0 +1,138 @@ +/**************************************************** +*Part of SPC2IT, read readme.md for more information* +****************************************************/ + +#include +#include +#include +#include +#include + +#include "sound.h" +#include "it.h" +#include "emu.h" +#include "sneese_spc.h" + +_Static_assert(sizeof(u8) == 1, "Warning: wrong size u8"); +_Static_assert(sizeof(u16) == 2, "Warning: wrong size u16"); +_Static_assert(sizeof(u32) == 4, "Warning: wrong size u32"); +_Static_assert(sizeof(u64) == 8, "Warning: wrong size u64"); +_Static_assert(sizeof(s8) == 1, "Warning: wrong size s8"); +_Static_assert(sizeof(s16) == 2, "Warning: wrong size s16"); +_Static_assert(sizeof(s32) == 4, "Warning: wrong size s32"); +_Static_assert(sizeof(s64) == 8, "Warning: wrong size s64"); +_Static_assert(sizeof(ITFileHeader) == 192, "Warning: wrong size ITFileHeader"); +_Static_assert(sizeof(ITFileSample) == 80, "Warning: wrong size ITFileSample"); +_Static_assert(sizeof(ITFilePattern) == 8, "Warning: wrong size ITFilePattern"); +_Static_assert(sizeof(SPCFile) == 65920, "Warning: wrong size SPCFile"); + +int spc2it_load(const char* src, int ITrows, int limit, int verbose) +{ + if (ITStart(ITrows)) + { + // printf("Error: failed to initialize pattern buffers\n"); + return(1); + } + if (SPCInit(src)) // Reset SPC and load state + { + // printf("Error: failed to initialize emulation\n"); + return(1); + } + if (SNDInit()) + { + // printf("Error: failed to initialize sound\n"); + return(1); + } + + if ((!limit) && (SPCtime)) + limit = SPCtime; + else if (!limit) + limit = 60; + + if (verbose) + { + printf("Time (seconds): %i\n", limit); + + printf("IT Parameters:\n"); + printf(" Rows/pattern: %d\n", ITrows); + + printf("ID info:\n"); + printf(" Song: %s\n", SPCInfo.SongTitle); + printf(" Game: %s\n", SPCInfo.GameTitle); + printf(" Dumper: %s\n", SPCInfo.DumperName); + printf(" Comments: %s\n", SPCInfo.Comment); + printf(" Created on: %s\n", SPCInfo.Date); + + printf("\n"); + + fflush(stdout); + } + + SNDNoteOn(SPC_DSP[0x4c]); + + int success = 1; + int seconds = SNDratecnt = 0; + while (true) + { + if (ITMix() || ITUpdate()) + return 1; + + SNDratecnt += 1; + + int ret = SPC_START(2048000 / (SPCUpdateRate * 2)); // emulate the SPC700 + + if (ret) + return 1; + + if (SNDratecnt >= SPCUpdateRate) + { + SNDratecnt -= SPCUpdateRate; + seconds++; // count number of seconds + + if (verbose) + { + printf("Progress: %f%%\r", (((f64)seconds / limit) * 100)); + fflush(stdout); + } + + if (seconds == limit) + break; + } + } + + return 0; +} + +int spc2it_save(const char* dest, int verbose) +{ + if (verbose) + printf("\n\nSaving file...\n"); + + if (ITWrite(dest)) + { + if (verbose) + printf("Error: failed to write %s.\n", dest); + + return 1; + } + + if (verbose) + printf("Wrote to %s successfully.\n", dest); + + return 0; +} + +void spc2it_cleanup() +{ + ITCleanup(); + Reset_SPC(); +} + +int spc2it_convert(const char* src, const char* dest) +{ + int failure = spc2it_load(src, 200, 0, 0) || spc2it_save(dest, 0); + + spc2it_cleanup(); + + return failure; +} diff --git a/src/lib.h b/src/lib.h new file mode 100644 index 0000000..ecc682d --- /dev/null +++ b/src/lib.h @@ -0,0 +1,12 @@ +/**************************************************** +*Part of SPC2IT, read readme.md for more information* +****************************************************/ + +#ifndef LIB_H +#define LIB_H + +int spc2it_load(const char* src, int ITrows, int limit, int verbose); +int spc2it_save(const char* dest, int verbose); +void spc2it_cleanup(); + +#endif diff --git a/src/main.c b/src/main.c index df05963..9069ea3 100644 --- a/src/main.c +++ b/src/main.c @@ -8,61 +8,23 @@ #include #include -#include "sound.h" -#include "it.h" -#include "emu.h" -#include "sneese_spc.h" +#include "lib.h" #ifdef _WIN32 #undef realpath #define realpath(N,R) _fullpath((R),(N),_MAX_PATH) #endif + int main(int argc, char **argv) { - size_t u8Size = sizeof(u8); - if (!(u8Size == 1)) - printf("Warning: wrong size u8: %zu \n", u8Size); - size_t u16Size = sizeof(u16); - if (!(u16Size == 2)) - printf("Warning: wrong size u16: %zu \n", u16Size); - size_t u32Size = sizeof(u32); - if (!(u32Size == 4)) - printf("Warning: wrong size u32: %zu \n", u32Size); - size_t u64Size = sizeof(u64); - if (!(u64Size == 8)) - printf("Warning: wrong size u64: %zu \n", u64Size); - size_t s8Size = sizeof(s8); - if (!(s8Size == 1)) - printf("Warning: wrong size s8: %zu \n", s8Size); - size_t s16Size = sizeof(s16); - if (!(s16Size == 2)) - printf("Warning: wrong size s16: %zu \n", s16Size); - size_t s32Size = sizeof(s32); - if (!(s32Size == 4)) - printf("Warning: wrong size s32: %zu \n", s32Size); - size_t s64Size = sizeof(s64); - if (!(s64Size == 8)) - printf("Warning: wrong size s64: %zu \n", s64Size); - size_t ITFileHeaderSize = sizeof(ITFileHeader); - if (!(ITFileHeaderSize == 192)) - printf("Warning: wrong size ITFileHeader: %zu \n", ITFileHeaderSize); - size_t ITFileSampleSize = sizeof(ITFileSample); - if (!(ITFileSampleSize == 80)) - printf("Warning: wrong size ITFileSample: %zu \n", ITFileSampleSize); - size_t ITFilePatternSize = sizeof(ITFilePattern); - if (!(ITFilePatternSize == 8)) - printf("Warning: wrong size ITFilePattern: %zu \n", ITFilePatternSize); - size_t SPCFileSize = sizeof(SPCFile); - if (!(SPCFileSize == 65920)) - printf("Warning: wrong size SPCFile: %zu \n", SPCFileSize); - s32 seconds, limit, ITrows; + int seconds, limit, ITrows; char fn[PATH_MAX]; - s32 i; fn[0] = 0; ITrows = 200; // Default 200 IT rows/pattern limit = 0; // Will be set later - for (i = 1; i < argc; i++) + + for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') switch (argv[i][1]) @@ -94,77 +56,10 @@ int main(int argc, char **argv) } printf("\n"); printf("Filepath: %s\n", fn); - if (ITStart(ITrows)) - { - printf("Error: failed to initialize pattern buffers\n"); - return(1); - } - if (SPCInit(fn)) // Reset SPC and load state - { - printf("Error: failed to initialize emulation\n"); - return(1); - } - if (SNDInit()) - { - printf("Error: failed to initialize sound\n"); - return(1); - } - - if ((!limit) && (SPCtime)) - limit = SPCtime; - else if (!limit) - limit = 60; - - printf("Time (seconds): %i\n", limit); - - printf("IT Parameters:\n"); - printf(" Rows/pattern: %d\n", ITrows); - - printf("ID info:\n"); - printf(" Song: %s\n", SPCInfo.SongTitle); - printf(" Game: %s\n", SPCInfo.GameTitle); - printf(" Dumper: %s\n", SPCInfo.DumperName); - printf(" Comments: %s\n", SPCInfo.Comment); - printf(" Created on: %s\n", SPCInfo.Date); - - printf("\n"); - - fflush(stdout); - - SNDNoteOn(SPC_DSP[0x4c]); - int success = 1; - seconds = SNDratecnt = 0; - while (true) - { - if (ITMix() || ITUpdate()) - { - success = 0; - break; - } - - SNDratecnt += 1; - - int ret = SPC_START(2048000 / (SPCUpdateRate * 2)); // emulate the SPC700 - - if (ret) - { - success = 0; - break; - } - - if (SNDratecnt >= SPCUpdateRate) - { - SNDratecnt -= SPCUpdateRate; - seconds++; // count number of seconds - printf("Progress: %f%%\r", (((f64)seconds / limit) * 100)); - fflush(stdout); - if (seconds == limit) - break; - } - } - printf("\n\nSaving file...\n"); + int load_ret = spc2it_load(fn, ITrows, limit, 1); + int i; for (i = 0; i < PATH_MAX; i++) if (fn[i] == 0) break; @@ -175,12 +70,9 @@ int main(int argc, char **argv) strcpy(&fn[i + 1], "it"); break; } - if (!success || ITWrite(fn)) - printf("Error: failed to write %s.\n", fn); - else - printf("Wrote to %s successfully.\n", fn); - Reset_SPC(); + if (!load_ret) + spc2it_save(fn, 1); - return !success; + spc2it_cleanup(); } diff --git a/src/spc2ittypes.h b/src/spc2ittypes.h index 4274e13..9680e1c 100644 --- a/src/spc2ittypes.h +++ b/src/spc2ittypes.h @@ -152,4 +152,4 @@ typedef struct u32 ar, dr, sl, sr, gn; } sndvoice; -#endif \ No newline at end of file +#endif