changeset 1246:7bd50496c9ec

Work on improved module conversion.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 07 Mar 2015 18:19:43 +0200
parents 2a0488078b78
children 5ae2ce21c7ae
files minijss/jssmod.h tools/xm2jss.c
diffstat 2 files changed, 115 insertions(+), 110 deletions(-) [+]
line wrap: on
line diff
--- a/minijss/jssmod.h	Sat Mar 07 17:58:06 2015 +0200
+++ b/minijss/jssmod.h	Sat Mar 07 18:19:43 2015 +0200
@@ -237,7 +237,7 @@
 
 typedef struct __attribute__((__packed__))
 {
-    Uint16
+    Uint8
         flags,
         npoints,
         sustain,
--- a/tools/xm2jss.c	Sat Mar 07 17:58:06 2015 +0200
+++ b/tools/xm2jss.c	Sat Mar 07 18:19:43 2015 +0200
@@ -423,21 +423,31 @@
 #undef JSFOREACHNOTE2
 
 
-static void jssCopyEnvelope(JSSMODEnvelope *je, JSSEnvelope *e)
+static BOOL jssMODWriteEnvelope(FILE *outFile, JSSEnvelope *env, const char *name, const int ninst)
 {
     int i;
+    BOOL ok =
+        dm_fwrite_byte(outFile, env->flags) &&
+        dm_fwrite_byte(outFile, env->npoints) &&
+        dm_fwrite_byte(outFile, env->sustain) &&
+        dm_fwrite_byte(outFile, env->loopS) &&
+        dm_fwrite_byte(outFile, env->loopE);
 
-    je->flags   = e->flags;
-    je->npoints = e->npoints;
-    je->sustain = e->sustain;
-    je->loopS   = e->loopS;
-    je->loopE   = e->loopE;
+    for (i = 0; ok && i < env->npoints; i++)
+    {
+        ok =
+            dm_fwrite_le16(outFile, env->points[i].frame) &&
+            dm_fwrite_le16(outFile, env->points[i].value);
+    }
 
-    for (i = 0; i < e->npoints; i++)
+    if (!ok)
     {
-        je->points[i].frame = e->points[i].frame;
-        je->points[i].value = e->points[i].value;
+        JSSERROR(DMERR_FWRITE, ok,
+        "Failed to write JSSMOD %s-envelope for instrument #%d.\n",
+        name, ninst);
     }
+
+    return ok;
 }
 
 
@@ -446,9 +456,10 @@
 int jssSaveJSSMOD(FILE *outFile, JSSModule *module, int patMode, int flags8, int flags16)
 {
     JSSMODHeader jssH;
-    int i, pattern, order, instr, totalSize;
     const size_t patBufSize = 256*1024; // 256kB pattern buffer
     Uint8 *patBuf;
+    size_t totalSize;
+    int index;
 
     // Check the module
     if (module == NULL)
@@ -503,13 +514,13 @@
     dmMsg(1," * JSSMOD-header 0x%04x, %d bytes.\n", JSSMOD_VERSION, totalSize);
 
     // Write orders list
-    for (totalSize = order = 0; order < module->norders; order++)
+    for (totalSize = index = 0; index < module->norders; index++)
     {
-        int tmp = module->orderList[order];
+        int tmp = module->orderList[index];
         if (tmp != jsetNotSet && tmp > module->npatterns)
             JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
             "Orderlist entry #%d has invalid value %d.\n",
-            order, tmp);
+            index, tmp);
 
         if (tmp == jsetNotSet)
             tmp = 0xffff;
@@ -517,7 +528,7 @@
         if (!dm_fwrite_le16(outFile, tmp))
             JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
             "Could not write JSSMOD orders list entry #%d (%d).\n",
-            order, tmp);
+            index, tmp);
 
         totalSize += sizeof(Uint16);
     }
@@ -531,148 +542,139 @@
         "Error allocating memory for pattern compression buffer.\n");
 
     // Convert and write patterns
-    for (totalSize = pattern = 0; pattern < module->npatterns; pattern++)
-    if (module->patterns[pattern] != NULL)
+    for (totalSize = index = 0; index < module->npatterns; index++)
+    if (module->patterns[index] != NULL)
     {
-        JSSPattern *pat = module->patterns[pattern];
-        JSSMODPattern patHead;
-        size_t finalSize = 0;
+        JSSPattern *pattern = module->patterns[index];
+        size_t dataSize = 0;
+        int ret;
 
-        if (pat->nrows > jsetMaxRows)
+        if (pattern->nrows > jsetMaxRows)
             JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
             "Pattern #%d has %d rows > %d max.\n",
-            pattern, pat->nrows, jsetMaxRows);
+            index, pattern->nrows, jsetMaxRows);
 
         switch (patMode)
         {
             case PATMODE_RAW_HORIZ:
-                i = jssConvertPatternRawHoriz(patBuf, patBufSize, &finalSize, pat);
+                ret = jssConvertPatternRawHoriz(patBuf, patBufSize, &dataSize, pattern);
                 break;
             case PATMODE_COMP_HORIZ:
-                i = jssConvertPatternCompHoriz(patBuf, patBufSize, &finalSize, pat);
+                ret = jssConvertPatternCompHoriz(patBuf, patBufSize, &dataSize, pattern);
                 break;
             case PATMODE_RAW_VERT:
-                i = jssConvertPatternRawVert(patBuf, patBufSize, &finalSize, pat);
+                ret = jssConvertPatternRawVert(patBuf, patBufSize, &dataSize, pattern);
                 break;
             case PATMODE_COMP_VERT:
-                i = jssConvertPatternCompVert(patBuf, patBufSize, &finalSize, pat);
+                ret = jssConvertPatternCompVert(patBuf, patBufSize, &dataSize, pattern);
                 break;
             case PATMODE_RAW_ELEM:
-                i = jssConvertPatternRawElem(patBuf, patBufSize, &finalSize, pat);
+                ret = jssConvertPatternRawElem(patBuf, patBufSize, &dataSize, pattern);
                 break;
             default:
-                dmFree(patBuf);
                 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
                 "Unsupported pattern conversion mode %d for pattern #%d.\n",
-                patMode, pattern);
+                patMode, index);
         }
 
-        if (i != DMERR_OK)
-        {
-            dmFree(patBuf);
-            JSSERROR(i, i, "Error converting pattern data #%d\n", pattern);
-        }
+        if (ret != DMERR_OK)
+            JSSERROR(ret, ret, "Error converting pattern data #%d.\n",
+            pattern);
 
-        dmMsg(3, " - Pattern %d size %d bytes\n", pattern, finalSize);
-        patHead.nrows = pat->nrows;
-        patHead.size = finalSize;
-        totalSize += finalSize + sizeof(patHead);
+        dmMsg(3, " - Pattern %d size %d bytes\n", index, dataSize);
+        totalSize += dataSize + sizeof(JSSMODPattern);
 
-        if (fwrite(&patHead, sizeof(patHead), 1, outFile) != 1)
-        {
-            dmFree(patBuf);
+        if (!dm_fwrite_le32(outFile, dataSize) ||
+            !dm_fwrite_le16(outFile, pattern->nrows) ||
+            !dm_fwrite_str(outFile, patBuf, dataSize))
             JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
-            "Error writing pattern #%d header\n", pattern);
-        }
-
-        if (fwrite(patBuf, sizeof(Uint8), finalSize, outFile) != finalSize)
-        {
-            dmFree(patBuf);
-            JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
-            "Error writing pattern #%d data\n", pattern);
-        }
+            "Error writing JSSMOD pattern #%d.\n",
+            index);
     }
     else
         JSSERROR(DMERR_NULLPTR, DMERR_NULLPTR,
-        "Pattern #%d was NULL.\n", pattern);
+        "Pattern #%d was NULL.\n", index);
 
     dmFree(patBuf);
-    dmMsg(1," * %d patterns, %d bytes.\n", module->npatterns, totalSize);
+    dmMsg(1," * %d patterns, %d bytes.\n",
+        module->npatterns, totalSize);
 
     // Write extended instruments
-    for (totalSize = instr = 0; instr < module->nextInstruments; instr++)
-    if (module->extInstruments[instr] != NULL)
+    for (totalSize = index = 0; index < module->nextInstruments; index++)
+    if (module->extInstruments[index] != NULL)
     {
-        JSSExtInstrument *einst = module->extInstruments[instr];
-        JSSMODExtInstrument jssE;
+        JSSExtInstrument *einst = module->extInstruments[index];
+        int i;
 
-        dmMemset(&jssE, 0, sizeof(jssE));
+        BOOL ok =
+            dm_fwrite_byte(outFile, einst->nsamples) &&
+            dm_fwrite_byte(outFile, einst->vibratoType) &&
+            dm_fwrite_le16(outFile, einst->vibratoSweep) &&
+            dm_fwrite_le16(outFile, einst->vibratoDepth) &&
+            dm_fwrite_le16(outFile, einst->vibratoRate) &&
+            dm_fwrite_le16(outFile, einst->fadeOut);
 
-        // Create header
-        jssE.nsamples = einst->nsamples;
-        for (i = 0; i < jsetNNotes; i++)
+        for (i = 0; ok && i < jsetNNotes; i++)
         {
             int snum = einst->sNumForNotes[i];
-            jssE.sNumForNotes[i] = (snum != jsetNotSet) ? snum + 1: 0;
+            Uint32 tmp = (snum != jsetNotSet) ? snum + 1 : 0;
+            ok = dm_fwrite_le32(outFile, tmp);
         }
 
-        jssCopyEnvelope(&jssE.volumeEnv, &(einst->volumeEnv));
-        jssCopyEnvelope(&jssE.panningEnv, &(einst->panningEnv));
-        jssE.vibratoType  = einst->vibratoType;
-        jssE.vibratoSweep = einst->vibratoSweep;
-        jssE.vibratoDepth = einst->vibratoDepth;
-        jssE.fadeOut      = einst->fadeOut;
-
-        // Write to file
-        totalSize += sizeof(jssE);
-        if (fwrite(&jssE, sizeof(jssE), 1, outFile) != 1)
+        if (!ok ||
+            !jssMODWriteEnvelope(outFile, &einst->volumeEnv, "volume", index) ||
+            !jssMODWriteEnvelope(outFile, &einst->panningEnv, "panning", index))
             JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
-            "Could not write JSSMOD extended instrument #%d to file!\n", instr);
-    } else
-        JSSWARNING(DMERR_NULLPTR, DMERR_NULLPTR, "Extended instrument #%d NULL!\n", instr);
-
-    dmMsg(1," * %d Extended Instruments, %d bytes.\n", module->nextInstruments, totalSize);
+            "Error writing JSSMOD extended instrument #%d.\n",
+            index);
 
-    // Write sample instrument headers
-    for (totalSize = instr = 0; instr < module->ninstruments; instr++)
-    if (module->instruments[instr] != NULL)
-    {
-        JSSInstrument *inst = module->instruments[instr];
-        JSSMODInstrument jssI;
-
-        dmMemset(&jssI, 0, sizeof(jssI));
-
-        // Create header
-        jssI.size         = inst->size;
-        jssI.loopS        = inst->loopS;
-        jssI.loopE        = inst->loopE;
-        jssI.volume       = inst->volume;
-        jssI.flags        = inst->flags;
-        jssI.C4BaseSpeed  = inst->C4BaseSpeed;
-        jssI.ERelNote     = inst->ERelNote;
-        jssI.EFineTune    = inst->EFineTune;
-        jssI.EPanning     = inst->EPanning;
-        jssI.convFlags    = (inst->flags & jsf16bit) ? flags16 : flags8;
-        if (inst->data != NULL)
-            jssI.convFlags |= jsampHasData;
-
-        // Write to file
-        totalSize += sizeof(jssI);
-        if (fwrite(&jssI, sizeof(jssI), 1, outFile) != 1)
-            JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
-             "Could not write JSSMOD instrument #%d to file!\n", instr);
+        totalSize += sizeof(JSSMODExtInstrument);
     }
     else
         JSSWARNING(DMERR_NULLPTR, DMERR_NULLPTR,
-        "Instrument #%d NULL!\n", instr);
+        "Extended instrument #%d NULL!\n",
+        index);
+
+    dmMsg(1," * %d Extended Instruments, %d bytes.\n",
+        module->nextInstruments, totalSize);
+
+    // Write sample instrument headers
+    for (totalSize = index = 0; index < module->ninstruments; index++)
+    if (module->instruments[index] != NULL)
+    {
+        JSSInstrument *inst = module->instruments[index];
+        Uint8 convFlags = (inst->flags & jsf16bit) ? flags16 : flags8;
+        if (inst->data != NULL)
+            convFlags |= jsampHasData;
+
+        // Write instrument header to file
+        if (!dm_fwrite_le32(outFile, inst->size) ||
+            !dm_fwrite_le32(outFile, inst->loopS) ||
+            !dm_fwrite_le32(outFile, inst->loopE) ||
+            !dm_fwrite_le16(outFile, inst->flags) ||
+            !dm_fwrite_le16(outFile, inst->C4BaseSpeed) ||
+            !dm_fwrite_le16(outFile, inst->ERelNote) ||
+            !dm_fwrite_le16(outFile, inst->EFineTune) ||
+            !dm_fwrite_le16(outFile, inst->EPanning) ||
+            !dm_fwrite_byte(outFile, inst->volume) ||
+            !dm_fwrite_byte(outFile, inst->convFlags))
+            JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
+            "Error writing JSSMOD instrument #%d.\n",
+            index);
+
+        totalSize += sizeof(JSSMODInstrument);
+    }
+    else
+        JSSWARNING(DMERR_NULLPTR, DMERR_NULLPTR,
+        "Instrument #%d NULL!\n", index);
 
     dmMsg(1," * %d Instrument headers, %d bytes.\n",
         module->ninstruments, totalSize);
 
     // Write sample data
-    for (totalSize = instr = 0; instr < module->ninstruments; instr++)
+    for (totalSize = index = 0; index < module->ninstruments; index++)
     {
-        JSSInstrument *inst = module->instruments[instr];
+        JSSInstrument *inst = module->instruments[index];
         if (inst != NULL && inst->data != NULL)
         {
             size_t bsize = inst->size;
@@ -687,14 +689,17 @@
                 jssEncodeSample8(inst->data, inst->size, flags8);
             }
 
-            if (fwrite(inst->data, sizeof(Uint16), bsize, outFile) != bsize)
+            if (!dm_fwrite_str(outFile, inst->data, bsize))
                 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
-                "Error writing JSSMOD sample #%d.\n", instr);
+                "Error writing JSSMOD sample data for instrument #%d.\n",
+                index);
 
             totalSize += bsize;
         }
     }
-    dmMsg(1," * %d samples, %d bytes.\n", module->ninstruments, totalSize);
+
+    dmMsg(1," * %d samples, %d bytes.\n",
+        module->ninstruments, totalSize);
 
     return DMERR_OK;
 }