changeset 2303:dcf1016f3d27

Implement new (horizontal raw element) pattern storage mode for JSSMOD. Bump JSSMOD format version.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 08 Jul 2019 10:06:18 +0300
parents 7c26b5f86ff7
children 9aa51ac4e502
files config.mak.in minijss/jloadjss.c minijss/jssmod.h tools/xm2jss.c
diffstat 4 files changed, 136 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/config.mak.in	Mon Jul 08 08:58:31 2019 +0300
+++ b/config.mak.in	Mon Jul 08 10:06:18 2019 +0300
@@ -83,6 +83,7 @@
 #JSSMOD_FLAGS += -DJM_SUP_PATMODE_3
 #JSSMOD_FLAGS += -DJM_SUP_PATMODE_4
 #JSSMOD_FLAGS += -DJM_SUP_PATMODE_5
+#JSSMOD_FLAGS += -DJM_SUP_PATMODE_6
 
 # Enable ext. instrument, instrument header and sampledata loading:
 # (if you disable these, you better know what you are doing.)
--- a/minijss/jloadjss.c	Mon Jul 08 08:58:31 2019 +0300
+++ b/minijss/jloadjss.c	Mon Jul 08 10:06:18 2019 +0300
@@ -13,6 +13,7 @@
 #    define JM_SUP_PATMODE_3 1
 #    define JM_SUP_PATMODE_4 1
 #    define JM_SUP_PATMODE_5 1
+#    define JM_SUP_PATMODE_6 1
 #endif
 
 
@@ -253,6 +254,64 @@
 
     return DMERR_OK;
 }
+
+#undef JSFOREACHNOTE1
+#undef JSFOREACHNOTE2
+#endif
+
+
+#ifdef JM_SUP_PATMODE_6
+
+#undef JSGETBYTE
+#define JSGETBYTE(XV) if (!dmf_read_byte(inFile, XV)) return DMERR_OUT_OF_DATA
+
+#define JSFOREACHNOTE1 \
+    for (int row = 0; row < pattern->nrows; row++) \
+    for (int channel = 0; channel < pattern->nmap; channel++) { \
+        JSSNote *pnote = pattern->data + (pattern->nchannels * row) + pattern->map[channel];
+
+#define JSFOREACHNOTE2 }
+
+
+static int jssGetPatternRawHorizElem(DMResource *inFile, JSSPattern *pattern)
+{
+    Uint8 tmp;
+
+    JSFOREACHNOTE1
+    JSGETBYTE(&tmp);
+    if (tmp == 0)
+        pnote->note = jsetNotSet;
+    else if (tmp == 127)
+        pnote->note = jsetNoteOff;
+    else
+        pnote->note = tmp - 1;
+    JSFOREACHNOTE2
+
+    JSFOREACHNOTE1
+    JSGETBYTE(&tmp);
+    pnote->instrument = (tmp > 0) ? tmp - 1 : jsetNotSet;
+    JSFOREACHNOTE2
+
+    JSFOREACHNOTE1
+    JSGETBYTE(&tmp);
+    pnote->volume = (tmp > 0) ? tmp - 1 : jsetNotSet;
+    JSFOREACHNOTE2
+
+    JSFOREACHNOTE1
+    JSGETBYTE(&tmp);
+    pnote->effect = (tmp > 0) ? tmp - 1 : jsetNotSet;
+    JSFOREACHNOTE2
+
+    JSFOREACHNOTE1
+    JSGETBYTE(&tmp);
+    pnote->param = (tmp == 0 && pnote->effect == jsetNotSet) ? jsetNotSet : tmp;
+    JSFOREACHNOTE2
+
+    return DMERR_OK;
+}
+
+#undef JSFOREACHNOTE1
+#undef JSFOREACHNOTE2
 #endif
 
 
@@ -502,10 +561,15 @@
                 break;
 #endif
 #ifdef JM_SUP_PATMODE_5
-            case PATMODE_RAW_ELEM:
+            case PATMODE_RAW_ELEM_VERT:
                 ret = jssGetPatternRawVertElem(inFile, pattern);
                 break;
 #endif
+#ifdef JM_SUP_PATMODE_6
+            case PATMODE_RAW_ELEM_HORIZ:
+                ret = jssGetPatternRawHorizElem(inFile, pattern);
+                break;
+#endif
             default:
                 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
                 "Unsupported pattern mode %d. Check compilation options.",
--- a/minijss/jssmod.h	Mon Jul 08 08:58:31 2019 +0300
+++ b/minijss/jssmod.h	Mon Jul 08 10:06:18 2019 +0300
@@ -182,7 +182,7 @@
 
 #ifdef JSS_SUP_JSSMOD
 
-#define JSSMOD_VERSION    (0x30)
+#define JSSMOD_VERSION    (0x40)
 
 enum
 {
@@ -190,10 +190,12 @@
     PATMODE_COMP_HORIZ,
     PATMODE_RAW_VERT,
     PATMODE_COMP_VERT,
-    PATMODE_RAW_ELEM,
+    PATMODE_RAW_ELEM_HORIZ,
+    PATMODE_RAW_ELEM_VERT,
     PATMODE_LAST
 };
 
+
 /* JSSMOD typedefs
  */
 typedef struct
--- a/tools/xm2jss.c	Mon Jul 08 08:58:31 2019 +0300
+++ b/tools/xm2jss.c	Mon Jul 08 10:06:18 2019 +0300
@@ -40,6 +40,7 @@
     "Compressed horizontal (similar to XM modules)",
     "Raw vertical",
     "Compressed vertical",
+    "Raw horizontal for each element",
     "Raw vertical for each element",
 };
 
@@ -392,16 +393,72 @@
 }
 
 
-#define JSFOREACHNOTE1                                                              \
-  for (channel = 0; channel < pattern->nchannels; channel++)                        \
-  for (row = 0; row < pattern->nrows; row++) {                                      \
+#define JSFOREACHNOTE1                                         \
+  for (channel = 0; channel < pattern->nchannels; channel++)   \
+  for (row = 0; row < pattern->nrows; row++) {                 \
   const JSSNote *pnote = jssGetNotePtr(pattern, channel, row); \
   if (pnote != NULL) {
 
 #define JSFOREACHNOTE2 } }
 
 
-static int jssConvertPatternRawElem(
+static int jssConvertPatternRawElemVert(
+    Uint8 *patBuf, const size_t patBufSize,
+    size_t *patSize, const JSSPattern *pattern)
+{
+    Uint8 tmp;
+    int row, channel;
+    *patSize = 0;
+
+    JSFOREACHNOTE1;
+    if (pnote->note == jsetNotSet)
+        tmp = 0;
+    else
+    if (pnote->note == jsetNoteOff)
+        tmp = 127;
+    else
+        tmp = pnote->note + 1;
+
+    if (tmp > 0x7f)
+        JSSERROR(DMERR_BOUNDS, DMERR_BOUNDS, "Note value out of bounds %d > 0x7f.\n", tmp);
+
+    JSPUTBYTE(tmp);
+    JSFOREACHNOTE2;
+
+    JSFOREACHNOTE1;
+    JSCONVPUT(pnote->instrument, "Instrument");
+    JSFOREACHNOTE2;
+
+    JSFOREACHNOTE1;
+    JSCONVPUT(pnote->volume, "Volume");
+    JSFOREACHNOTE2;
+
+    JSFOREACHNOTE1;
+    JSCONVPUT(pnote->effect, "Effect");
+    JSFOREACHNOTE2;
+
+    JSFOREACHNOTE1;
+    tmp = (pnote->param != jsetNotSet) ? pnote->param : 0;
+    JSPUTBYTE(tmp);
+    JSFOREACHNOTE2;
+
+    return DMERR_OK;
+}
+
+#undef JSFOREACHNOTE1
+#undef JSFOREACHNOTE2
+
+
+#define JSFOREACHNOTE1                                         \
+  for (row = 0; row < pattern->nrows; row++)                   \
+  for (channel = 0; channel < pattern->nchannels; channel++) { \
+  const JSSNote *pnote = jssGetNotePtr(pattern, channel, row); \
+  if (pnote != NULL) {
+
+#define JSFOREACHNOTE2 } }
+
+
+static int jssConvertPatternRawElemHoriz(
     Uint8 *patBuf, const size_t patBufSize,
     size_t *patSize, const JSSPattern *pattern)
 {
@@ -610,8 +667,11 @@
             case PATMODE_COMP_VERT:
                 ret = jssConvertPatternCompVert(patBuf, patBufSize, &dataSize, pattern);
                 break;
-            case PATMODE_RAW_ELEM:
-                ret = jssConvertPatternRawElem(patBuf, patBufSize, &dataSize, pattern);
+            case PATMODE_RAW_ELEM_HORIZ:
+                ret = jssConvertPatternRawElemHoriz(patBuf, patBufSize, &dataSize, pattern);
+                break;
+            case PATMODE_RAW_ELEM_VERT:
+                ret = jssConvertPatternRawElemVert(patBuf, patBufSize, &dataSize, pattern);
                 break;
             default:
                 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA,