Mercurial > hg > dmlib
view tools/gentab.c @ 2049:a945a5f2fd70
Improve the cdump output format support of gfxconv. Also add some error handling.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 03 Dec 2018 18:58:45 +0200 |
parents | a9516570cc26 |
children | e3f0eaf23f4f |
line wrap: on
line source
#include "dmtool.h" #include "dmlib.h" #include "dmargs.h" #include "dmcurves.h" #include <math.h> 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 const 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, 0); 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) { dmErrorMsg("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; } } dmErrorMsg("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) { dmErrorMsg("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: dmErrorMsg("Unknown argument '%s'.\n", currArg); return FALSE; } return TRUE; } int main(int argc, char *argv[]) { FILE *outFile; DMLerpContext ctx; int step, n; dmInitProg("gentab", "Table generator", "0.2", NULL, NULL); dmVerbosity = 1; // Parse arguments if (!dmArgsProcess(argc, argv, optList, optListN, argHandleOpt, NULL, OPTH_BAILOUT)) exit(1); // Check settings if (optTransType < 0) { dmErrorMsg("No transformation type set, perhaps try --help\n"); return -1; } if (optObjectName == NULL) { dmErrorMsg("Object name not specified, try --help\n"); return -2; } if (optOutFilename == NULL) outFile = stdout; else if ((outFile = fopen(optOutFilename, "w")) == NULL) { int err = dmGetErrno(); dmErrorMsg("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; }