Mercurial > hg > dmlib
view gentab.c @ 510:43ea59887c69
Start work on making C64 formats encoding possible by changing DMDecodeOps
to DMEncDecOps and adding fields and op enums for custom encode functions, renaming,
etc. Split generic op sanity checking into a separate function in
preparation for its use in generic encoding function.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 19 Nov 2012 15:06:01 +0200 |
parents | 966617f0f6cd |
children |
line wrap: on
line source
#include "dmlib.h" #include "dmargs.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 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; }