# HG changeset patch # User Matti Hamalainen # Date 1353109979 -7200 # Node ID 966617f0f6cd7de8036d9949ff2d203298f6f252 # Parent 30145d17aebde1b775f870ddc5dce4310804a89b Add a simple utility for generating different sinus, etc. value tables in c64 assembler format. diff -r 30145d17aebd -r 966617f0f6cd Makefile.gen --- a/Makefile.gen Fri Nov 16 19:18:03 2012 +0200 +++ b/Makefile.gen Sat Nov 17 01:52:59 2012 +0200 @@ -192,7 +192,7 @@ ifeq ($(DM_BUILD_TOOLS),yes) DMLIB_OBJS += libgfx.o lib64gfx.o ifeq ($(DM_USE_STDIO),yes) -BINARIES+= objlink data2inc gfxconv +BINARIES+= objlink data2inc gfxconv gentab ifeq ($(SUP_MODLOAD),yes) BINARIES+= viewmod mod2wav testpl ifeq ($(DM_GFX_BLITS),yes) @@ -391,6 +391,10 @@ @echo " LINK $+" @$(CC) -o $@ $(filter %.o %.a,$+) $(DM_LDFLAGS) $(SDL_LDFLAGS) +$(BINPATH)gentab$(EXEEXT): $(OBJPATH)gentab.o $(DMLIB_A) + @echo " LINK $+" + @$(CC) -o $@ $(filter %.o %.a,$+) $(DM_LDFLAGS) -lm + ### ### Editor targets diff -r 30145d17aebd -r 966617f0f6cd gentab.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gentab.c Sat Nov 17 01:52:59 2012 +0200 @@ -0,0 +1,264 @@ +#include "dmlib.h" +#include "dmargs.h" +#include + +enum +{ + MT_SIN, + MT_COS, + MT_SMOOTH1, + MT_SCURVE, + MT_SMOOTH1_CLAMP, + MT_SCURVE_CLAMP, + MT_SIN_SCURVE, + + MT_LAST +}; + + +typedef struct +{ + char *name; + char *desc; +} DMTransType; + +static DMTransType dmTransTypes[MT_LAST] = +{ + { "sin", "Sine" }, + { "cos", "Cosine" }, + { "smooth1", "Smoothstep1 LERP" }, + { "scurve", "S-curve LERP" }, + { "smooth1-clamp", "Clamped smoothstep1 LERP" }, + { "scurve-clamp", "Clamped S-curve LERP" }, + { "sin-scurve", "Sine S-curve" }, +}; + + +DMFloat + optSOffset = 0.0f, + optSAmplitude = 1.0f, + optSOmega = 1.0f, + optStartValue = 0.0f, + optEndValue = 1.0f; + +int optNSteps = 64, + optPerLine = 16, + optTransType = -1; + +char + *optObjectName = NULL, + *optOutFilename = NULL; + + +static DMOptArg optList[] = +{ + { 0, '?', "help", "Show this help", OPT_NONE }, + { 1, 'v', "verbose", "Increase verbosity", OPT_NONE }, + { 2, 'o', "output", "Set output file (default stdout)", OPT_ARGREQ }, + { 3, 'n', "name", "Set output object name", OPT_ARGREQ }, + + { 4, 's', "steps", "Number of steps/values in output table", OPT_ARGREQ }, + { 5, 't', "type", "Curve/interpolation type (see list)", OPT_ARGREQ }, + + { 6, 'O', "offset", "Output data offset", OPT_ARGREQ }, + { 7, 'A', "amplitude", "Output amplitude scale", OPT_ARGREQ }, + { 8, 'W', "omega", "Omega (w) multiplier", OPT_ARGREQ }, + + { 9, 'S', "start", "Start value (only smooth/scurve)", OPT_ARGREQ }, + { 10, 'E', "end", "End value (only smooth/scurve)", OPT_ARGREQ }, +}; + +static const int optListN = sizeof(optList) / sizeof(optList[0]); + + +void argShowHelp() +{ + int index; + dmPrintBanner(stdout, dmProgName, "[options]"); + dmArgsPrintHelp(stdout, optList, optListN); + + printf("\nAvailable types:\n"); + for (index = 0; index < MT_LAST; index++) + { + DMTransType *tm = &dmTransTypes[index]; + printf("%-15s | %s\n", tm->name, tm->desc); + } + printf("\n"); +} + + +BOOL argHandleOpt(const int optN, char *optArg, char *currArg) +{ + switch (optN) + { + case 0: + argShowHelp(); + exit(0); + break; + + case 1: + dmVerbosity++; + break; + + case 2: + optOutFilename = optArg; + break; + + case 3: + optObjectName = optArg; + break; + + case 4: + { + int tmp; + if (sscanf(optArg, "%d", &tmp) != 1) + { + dmError("Invalid number of steps argument '%s'.\n", optArg); + return FALSE; + } + optNSteps = tmp; + } + break; + + case 5: + { + int index; + for (index = 0; index < MT_LAST; index++) + { + DMTransType *tm = &dmTransTypes[index]; + if (strcasecmp(tm->name, optArg) == 0) + { + optTransType = index; + return TRUE; + } + } + dmError("Invalid transformation type option '%s'.\n", + optArg); + return FALSE; + } + break; + + case 6: + case 7: + case 8: + case 9: + case 10: + { + DMFloat tmp; + if (sscanf(optArg, "%f", &tmp) != 1) + { + dmError("Invalid %s option argument '%s', expected a floating point value.\n", + currArg, optArg); + return FALSE; + } + switch (optN) + { + case 6: optSOffset = tmp; break; + case 7: optSAmplitude = tmp; break; + case 8: optSOmega = tmp; break; + case 9: optStartValue = tmp; break; + case 10: optEndValue = tmp; break; + } + } + break; + + default: + dmError("Unknown argument '%s'.\n", currArg); + return FALSE; + } + + return TRUE; +} + + +int main(int argc, char *argv[]) +{ + FILE *outFile; + DMLerpContext ctx; + int step, n; + + dmInitProg("gentab", "Sine, etc. table generator", "0.1", NULL, NULL); + dmVerbosity = 1; + + // Parse arguments + if (!dmArgsProcess(argc, argv, optList, optListN, + argHandleOpt, NULL, TRUE)) + exit(1); + + // Check settings + if (optTransType < 0) + { + dmError("No transformation type set, perhaps try --help\n"); + return -1; + } + + if (optObjectName == NULL) + { + dmError("Object name not specified, try --help\n"); + return -2; + } + + if (optOutFilename == NULL) + outFile = stdout; + else + if ((outFile = fopen(optOutFilename, "w")) == NULL) + { + int err = dmGetErrno(); + dmError("Could not open output file '%s', %d: %s\n", + optOutFilename, err, dmErrorStr(err)); + return -2; + } + + + // Generate table + dmLerpInit(&ctx, optStartValue, optEndValue, optNSteps); + + fprintf(outFile, + "cnt_%s = %d\n" + "vtab_%s: ", + optObjectName, + optNSteps, + optObjectName + ); + + for (n = 0, step = 0; step < optNSteps; step++) + { + DMFloat t = ((DMFloat) step * optSOmega) / (DMFloat) optNSteps, delta, value; + + switch (optTransType) + { + case MT_SIN: delta = sin(t * 2 * DM_PI); break; + case MT_COS: delta = cos(t * 2 * DM_PI); break; + + case MT_SMOOTH1: delta = dmLerp1(&ctx, step); break; + case MT_SCURVE: delta = dmLerpSCurve(&ctx, step); break; + case MT_SMOOTH1_CLAMP: delta = dmLerp1Clamp(&ctx, step); break; + case MT_SCURVE_CLAMP: delta = dmLerpSCurveClamp(&ctx, step); break; + case MT_SIN_SCURVE: delta = dmLerpSCurveClamp(&ctx, step); break; + + default: delta = 0; + } + + value = optSOffset + delta * optSAmplitude; + + // Print the value + if (n == 0) + fprintf(outFile, "\t.byte "); + + fprintf(outFile, "%ld%s", + lrint(value), + (n < optPerLine - 1) ? "," : ""); + + if (++n >= optPerLine) + { + fprintf(outFile, "\n"); + n = 0; + } + } + if (n > 0) + fprintf(outFile, "\n"); + + fprintf(outFile, "\n"); + + return 0; +}