comparison tools/xm2jss.c @ 2474:e2e94f9afe1b

Various cleanups, use saner variable names.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 27 Apr 2020 18:08:39 +0300
parents f5848606d5ad
children b9734859db5c
comparison
equal deleted inserted replaced
2473:f5848606d5ad 2474:e2e94f9afe1b
915 } 915 }
916 916
917 917
918 /* Optimize a given module 918 /* Optimize a given module
919 */ 919 */
920 JSSModule *jssOptimizeModule(JSSModule *m) 920 JSSModule *jssOptimizeModule(JSSModule *src)
921 { 921 {
922 BOOL usedPatterns[jsetMaxPatterns + 1], 922 BOOL usedPatterns[jsetMaxPatterns + 1],
923 usedInstruments[jsetMaxInstruments + 1], 923 usedInstruments[jsetMaxInstruments + 1],
924 usedExtInstruments[jsetMaxInstruments + 1]; 924 usedExtInstruments[jsetMaxInstruments + 1];
925 int mapExtInstruments[jsetMaxInstruments + 1], 925 int mapExtInstruments[jsetMaxInstruments + 1],
926 mapInstruments[jsetMaxInstruments + 1], 926 mapInstruments[jsetMaxInstruments + 1],
927 mapPatterns[jsetMaxPatterns + 1], 927 mapPatterns[jsetMaxPatterns + 1],
928 dupPatterns[jsetMaxPatterns + 1]; 928 dupPatterns[jsetMaxPatterns + 1];
929 929
930 JSSModule *r = NULL; 930 JSSModule *dst = NULL;
931 int n8, n16, nunused, ndupes; 931 int n8, n16, nunused, ndupes;
932 932
933 // Allocate a new module 933 // Allocate a new module
934 if ((r = jssAllocateModule()) == NULL) 934 if ((dst = jssAllocateModule()) == NULL)
935 return NULL; 935 return NULL;
936 936
937 // Copy things 937 // Copy things
938 r->moduleType = m->moduleType; 938 dst->moduleType = src->moduleType;
939 r->moduleName = dm_strdup(m->moduleName); 939 dst->moduleName = src->moduleName;
940 r->trackerName = dm_strdup(m->trackerName); 940 dst->trackerName = src->trackerName;
941 r->defSpeed = m->defSpeed; 941 dst->defSpeed = src->defSpeed;
942 r->defTempo = m->defTempo; 942 dst->defTempo = src->defTempo;
943 r->defFlags = m->defFlags; 943 dst->defFlags = src->defFlags;
944 r->defRestartPos = m->defRestartPos; 944 dst->defRestartPos = src->defRestartPos;
945 r->intVersion = m->intVersion; 945 dst->intVersion = src->intVersion;
946 r->nchannels = m->nchannels; 946 dst->nchannels = src->nchannels;
947 r->norders = m->norders; 947 dst->norders = src->norders;
948 948
949 for (int i = 0; i < jsetNChannels; i++) 949 for (int i = 0; i < jsetNChannels; i++)
950 { 950 {
951 r->defPanning[i] = m->defPanning[i]; 951 dst->defPanning[i] = src->defPanning[i];
952 } 952 }
953 953
954 // Initialize values 954 // Initialize values
955 for (int i = 0; i <= jsetMaxInstruments; i++) 955 for (int i = 0; i <= jsetMaxInstruments; i++)
956 { 956 {
970 // 970 //
971 // Find out all actually used patterns and ext.instruments 971 // Find out all actually used patterns and ext.instruments
972 // by going through all patterns specified in the order list 972 // by going through all patterns specified in the order list
973 // 973 //
974 dmMsg(1, "Scanning patterns for used instruments and channels...\n"); 974 dmMsg(1, "Scanning patterns for used instruments and channels...\n");
975 for (int norder = 0; norder < m->norders; norder++) 975 for (int norder = 0; norder < src->norders; norder++)
976 { 976 {
977 int npat = m->orderList[norder]; 977 int npat = src->orderList[norder];
978 if (npat >= 0 && npat < m->npatterns) 978 if (npat >= 0 && npat < src->npatterns)
979 { 979 {
980 JSSPattern *pattern = m->patterns[npat]; 980 JSSPattern *pattern = src->patterns[npat];
981 if (pattern != NULL) 981 if (pattern != NULL)
982 { 982 {
983 // Scan for used instruments etc 983 // Scan for used instruments etc
984 BOOL empty = jssScanPattern(m, pattern, npat, usedExtInstruments, NULL); 984 BOOL empty = jssScanPattern(src, pattern, npat, usedExtInstruments, NULL);
985 985
986 // Empty patterns with known number of rows are "removed" 986 // Empty patterns with known number of rows are "removed"
987 if (empty && pattern->nrows == jsetDefaultRows) 987 if (empty && pattern->nrows == jsetDefaultRows)
988 { 988 {
989 m->orderList[norder] = jsetNotSet; 989 src->orderList[norder] = jsetNotSet;
990 usedPatterns[npat] = FALSE; 990 usedPatterns[npat] = FALSE;
991 } 991 }
992 else 992 else
993 usedPatterns[npat] = TRUE; 993 usedPatterns[npat] = TRUE;
994 } 994 }
996 { 996 {
997 dmErrorMsg("Pattern 0x%x is used on order 0x%x, but has no data!\n", 997 dmErrorMsg("Pattern 0x%x is used on order 0x%x, but has no data!\n",
998 npat, norder); 998 npat, norder);
999 999
1000 // Fix it. 1000 // Fix it.
1001 m->orderList[norder] = jsetNotSet; 1001 src->orderList[norder] = jsetNotSet;
1002 } 1002 }
1003 } 1003 }
1004 else 1004 else
1005 if (npat != jsetNotSet) 1005 if (npat != jsetNotSet)
1006 { 1006 {
1007 dmErrorMsg("Order 0x%x has invalid pattern number 0x%x, changing to empty!\n", 1007 dmErrorMsg("Order 0x%x has invalid pattern number 0x%x, changing to empty!\n",
1008 norder, npat); 1008 norder, npat);
1009 1009
1010 // Fix it. 1010 // Fix it.
1011 m->orderList[norder] = jsetNotSet; 1011 src->orderList[norder] = jsetNotSet;
1012 } 1012 }
1013 } 1013 }
1014 1014
1015 // 1015 //
1016 // Find used sample instruments 1016 // Find used sample instruments
1017 // 1017 //
1018 dmMsg(1, "Checking ext.instruments for used sample instruments...\n"); 1018 dmMsg(1, "Checking ext.instruments for used sample instruments...\n");
1019 for (int i = 0; i < jsetMaxInstruments; i++) 1019 for (int neinst = 0; neinst < jsetMaxInstruments; neinst++)
1020 if (usedExtInstruments[i] && m->extInstruments[i] != NULL) 1020 if (usedExtInstruments[neinst] && src->extInstruments[neinst] != NULL)
1021 { 1021 {
1022 JSSExtInstrument *e = m->extInstruments[i]; 1022 JSSExtInstrument *eip = src->extInstruments[neinst];
1023 1023
1024 for (int note = 0; note < jsetNNotes; note++) 1024 for (int note = 0; note < jsetNNotes; note++)
1025 if (e->sNumForNotes[note] != jsetNotSet) 1025 if (eip->sNumForNotes[note] != jsetNotSet)
1026 { 1026 {
1027 int q = e->sNumForNotes[note]; 1027 int q = eip->sNumForNotes[note];
1028 if (q >= 0 && q < m->ninstruments) 1028 if (q >= 0 && q < src->ninstruments)
1029 { 1029 {
1030 usedInstruments[q] = TRUE; 1030 usedInstruments[q] = TRUE;
1031 } 1031 }
1032 else 1032 else
1033 { 1033 {
1034 dmErrorMsg("Ext.instrument #%d sNumForNotes[%d] value out range (%d < %d).\n", 1034 dmErrorMsg("Ext.instrument #%d sNumForNotes[%d] value out range (%d < %d).\n",
1035 i + 1, note, m->ninstruments, q + 1); 1035 neinst + 1, note, src->ninstruments, q + 1);
1036 } 1036 }
1037 } 1037 }
1038 } 1038 }
1039 1039
1040 // 1040 //
1044 nunused = ndupes = 0; 1044 nunused = ndupes = 0;
1045 for (int pat1 = 0; pat1 <= jsetMaxPatterns; pat1++) 1045 for (int pat1 = 0; pat1 <= jsetMaxPatterns; pat1++)
1046 if (usedPatterns[pat1]) 1046 if (usedPatterns[pat1])
1047 { 1047 {
1048 // Sanity check patterns 1048 // Sanity check patterns
1049 if (pat1 >= m->npatterns) 1049 if (pat1 >= src->npatterns)
1050 { 1050 {
1051 dmErrorMsg("Pattern 0x%x >= 0x%x, but used!\n", pat1, m->npatterns); 1051 dmErrorMsg("Pattern 0x%x >= 0x%x, but used!\n", pat1, src->npatterns);
1052 continue; 1052 continue;
1053 } 1053 }
1054 1054
1055 if (m->patterns[pat1] == NULL) 1055 if (src->patterns[pat1] == NULL)
1056 { 1056 {
1057 dmErrorMsg("Pattern 0x%x used but is NULL.\n", pat1); 1057 dmErrorMsg("Pattern 0x%x used but is NULL.\n", pat1);
1058 continue; 1058 continue;
1059 } 1059 }
1060 1060
1064 mapPatterns[pat1] = dupPatterns[pat1]; 1064 mapPatterns[pat1] = dupPatterns[pat1];
1065 continue; 1065 continue;
1066 } 1066 }
1067 1067
1068 // Check for duplicate patterns of "pat1" and mark them as such 1068 // Check for duplicate patterns of "pat1" and mark them as such
1069 for (int pat2 = 0; pat2 < m->npatterns; pat2++) 1069 for (int pat2 = 0; pat2 < src->npatterns; pat2++)
1070 if (pat1 != pat2 && m->patterns[pat2] != NULL && 1070 if (pat1 != pat2 && src->patterns[pat2] != NULL &&
1071 dupPatterns[pat2] == jsetNotSet && 1071 dupPatterns[pat2] == jsetNotSet &&
1072 jssComparePattern(m->patterns[pat1], m->patterns[pat2])) 1072 jssComparePattern(src->patterns[pat1], src->patterns[pat2]))
1073 { 1073 {
1074 dmPrint(1, " * %d and %d are dupes.\n", pat1, pat2); 1074 dmPrint(1, " * %d and %d are dupes.\n", pat1, pat2);
1075 dupPatterns[pat2] = pat1; 1075 dupPatterns[pat2] = pat1;
1076 ndupes++; 1076 ndupes++;
1077 } 1077 }
1078 1078
1079 mapPatterns[pat1] = r->npatterns; 1079 mapPatterns[pat1] = dst->npatterns;
1080 r->patterns[r->npatterns] = m->patterns[pat1]; 1080 dst->patterns[dst->npatterns] = src->patterns[pat1];
1081 (r->npatterns)++; 1081 (dst->npatterns)++;
1082 } 1082 }
1083 else 1083 else
1084 if (m->patterns[pat1] != NULL) 1084 if (src->patterns[pat1] != NULL)
1085 nunused++; 1085 nunused++;
1086 1086
1087 dmMsg(1, "%d used patterns (%d unused, %d duplicates).\n", 1087 dmMsg(1, "%d used patterns (%d unused, %d duplicates).\n",
1088 r->npatterns, nunused, ndupes); 1088 dst->npatterns, nunused, ndupes);
1089 1089
1090 // 1090 //
1091 // Re-map instruments 1091 // Re-map instruments
1092 // 1092 //
1093 dmMsg(1, "Creating sample instrument remaps...\n"); 1093 dmMsg(1, "Creating sample instrument remaps...\n");
1094 nunused = n8 = n16 = 0; 1094 nunused = n8 = n16 = 0;
1095 for (int i = 0; i < jsetMaxInstruments; i++) 1095 for (int ninst = 0; ninst < jsetMaxInstruments; ninst++)
1096 if (usedInstruments[i]) 1096 if (usedInstruments[ninst])
1097 { 1097 {
1098 JSSInstrument *ip; 1098 JSSInstrument *ip;
1099 if (optStripInstr) 1099 if (optStripInstr)
1100 continue; 1100 continue;
1101 1101
1102 if (i >= m->ninstruments) 1102 if (ninst >= src->ninstruments)
1103 { 1103 {
1104 dmErrorMsg("Instrument 0x%x >= 0x%x, but used!\n", 1104 dmErrorMsg("Instrument 0x%x >= 0x%x, but used!\n",
1105 i + 1, m->ninstruments); 1105 ninst + 1, src->ninstruments);
1106 continue; 1106 continue;
1107 } 1107 }
1108 1108
1109 if ((ip = m->instruments[i]) == NULL) 1109 if ((ip = src->instruments[ninst]) == NULL)
1110 { 1110 {
1111 dmErrorMsg("Instrument 0x%x used but is NULL.\n", i + 1); 1111 dmErrorMsg("Instrument 0x%x used but is NULL.\n", ninst + 1);
1112 continue; 1112 continue;
1113 } 1113 }
1114 1114
1115 dmPrint(2, "%02x -> %02x : ", i + 1, r->ninstruments + 1); 1115 dmPrint(2, "%02x -> %02x : ", ninst + 1, dst->ninstruments + 1);
1116 1116
1117 mapInstruments[i] = r->ninstruments; 1117 mapInstruments[ninst] = dst->ninstruments;
1118 r->instruments[r->ninstruments] = ip; 1118 dst->instruments[dst->ninstruments] = ip;
1119 (r->ninstruments)++; 1119 (dst->ninstruments)++;
1120 1120
1121 if (ip->flags & jsf16bit) 1121 if (ip->flags & jsf16bit)
1122 n16++; 1122 n16++;
1123 else 1123 else
1124 n8++; 1124 n8++;
1125 } 1125 }
1126 else 1126 else
1127 if (m->instruments[i] != NULL) 1127 if (src->instruments[ninst] != NULL)
1128 nunused++; 1128 nunused++;
1129 1129
1130 dmPrint(2, "\n"); 1130 dmPrint(2, "\n");
1131 dmMsg(1, "Total of %d [16-bit] + %d [8-bit] samples = %d instruments (%d unused).\n", 1131 dmMsg(1, "Total of %d [16-bit] + %d [8-bit] samples = %d instruments (%d unused).\n",
1132 n16, n8, r->ninstruments, nunused); 1132 n16, n8, dst->ninstruments, nunused);
1133 1133
1134 // 1134 //
1135 // Re-map ext.instruments 1135 // Re-map ext.instruments
1136 // 1136 //
1137 dmMsg(1, "Creating ext.instrument remaps...\n"); 1137 dmMsg(1, "Creating ext.instrument remaps...\n");
1138 nunused = 0; 1138 nunused = 0;
1139 for (int i = 0; i < jsetMaxInstruments; i++) 1139 for (int neinst = 0; neinst < jsetMaxInstruments; neinst++)
1140 if (usedExtInstruments[i]) 1140 if (usedExtInstruments[neinst])
1141 { 1141 {
1142 JSSExtInstrument *eip; 1142 JSSExtInstrument *eip;
1143 1143
1144 if (optStripExtInstr) 1144 if (optStripExtInstr)
1145 continue; 1145 continue;
1146 1146
1147 if (i >= m->nextInstruments) 1147 if (neinst >= src->nextInstruments)
1148 { 1148 {
1149 dmErrorMsg("Ext.instrument 0x%x >= 0x%x, but used!\n", 1149 dmErrorMsg("Ext.instrument 0x%x >= 0x%x, but used!\n",
1150 i + 1, m->nextInstruments); 1150 neinst + 1, src->nextInstruments);
1151 continue; 1151 continue;
1152 } 1152 }
1153 1153
1154 if ((eip = m->extInstruments[i]) == NULL) 1154 if ((eip = src->extInstruments[neinst]) == NULL)
1155 { 1155 {
1156 dmErrorMsg("Extended instrument 0x%x used but is NULL.\n", i + 1); 1156 dmErrorMsg("Extended instrument 0x%x used but is NULL.\n", neinst + 1);
1157 continue; 1157 continue;
1158 } 1158 }
1159 1159
1160 dmPrint(2, "%02x -> %02x : ", i + 1, r->nextInstruments + 1); 1160 dmPrint(2, "%02x -> %02x : ", neinst + 1, dst->nextInstruments + 1);
1161 1161
1162 mapExtInstruments[i] = r->nextInstruments; 1162 mapExtInstruments[neinst] = dst->nextInstruments;
1163 r->extInstruments[r->nextInstruments] = eip; 1163 dst->extInstruments[dst->nextInstruments] = eip;
1164 (r->nextInstruments)++; 1164 (dst->nextInstruments)++;
1165 1165
1166 // Re-map sNumForNotes table for this ext.instrument 1166 // Re-map sNumForNotes table for this ext.instrument
1167 for (int note = 0; note < jsetNNotes; note++) 1167 for (int note = 0; note < jsetNNotes; note++)
1168 { 1168 {
1169 int q = eip->sNumForNotes[note]; 1169 int q = eip->sNumForNotes[note];
1176 } 1176 }
1177 else 1177 else
1178 { 1178 {
1179 map = jsetNotSet; 1179 map = jsetNotSet;
1180 dmErrorMsg("Einst=%d, note=%d, sNumForNote=%d (%d max)\n", 1180 dmErrorMsg("Einst=%d, note=%d, sNumForNote=%d (%d max)\n",
1181 i + 1, note, q + 1, r->ninstruments); 1181 neinst + 1, note, q + 1, dst->ninstruments);
1182 } 1182 }
1183 1183
1184 dmPrint(3, "%02x.%02x ", q + 1, map + 1); 1184 dmPrint(3, "%02x.%02x ", q + 1, map + 1);
1185 eip->sNumForNotes[note] = map; 1185 eip->sNumForNotes[note] = map;
1186 } 1186 }
1187 } 1187 }
1188 } 1188 }
1189 else 1189 else
1190 if (m->extInstruments[i] != NULL) 1190 if (src->extInstruments[neinst] != NULL)
1191 nunused++; 1191 nunused++;
1192 1192
1193 dmPrint(2, "\n"); 1193 dmPrint(2, "\n");
1194 dmMsg(1, "%d extended instruments (%d unused).\n", 1194 dmMsg(1, "%d extended instruments (%d unused).\n",
1195 r->nextInstruments, nunused); 1195 dst->nextInstruments, nunused);
1196 1196
1197 // 1197 //
1198 // Remap pattern data with remapped instrument data 1198 // Remap pattern data with remapped instrument data
1199 // 1199 //
1200 for (int i = 0; i < r->npatterns; i++) 1200 for (int npat = 0; npat < dst->npatterns; npat++)
1201 { 1201 {
1202 JSSPattern *p = r->patterns[i]; 1202 JSSPattern *pat = dst->patterns[npat];
1203 JSSNote *n = p->data; 1203 JSSNote *note = pat->data;
1204 1204
1205 for (int row = 0; row < p->nrows; row++) 1205 for (int row = 0; row < pat->nrows; row++)
1206 for (int channel = 0; channel < p->nchannels; channel++, n++) 1206 for (int channel = 0; channel < pat->nchannels; channel++, note++)
1207 { 1207 {
1208 // If not stripping extended instruments, check for 1208 // If not stripping extended instruments, check for
1209 // the validity of the used instrument and remap 1209 // the validity of the used instrument and remap
1210 if (!optStripExtInstr) 1210 if (!optStripExtInstr)
1211 { 1211 {
1212 if (n->instrument >= 0 && n->instrument < jsetMaxInstruments) 1212 if (note->instrument >= 0 && note->instrument < jsetMaxInstruments)
1213 n->instrument = mapExtInstruments[n->instrument]; 1213 note->instrument = mapExtInstruments[note->instrument];
1214 1214
1215 if (n->instrument != jsetNotSet && 1215 if (note->instrument != jsetNotSet &&
1216 r->extInstruments[n->instrument] == NULL) 1216 dst->extInstruments[note->instrument] == NULL)
1217 { 1217 {
1218 dmErrorMsg("Non-existing instrument used #%d, INTERNAL ERROR.\n", 1218 dmErrorMsg("Non-existing instrument used #%d, INTERNAL ERROR.\n",
1219 n->instrument + 1); 1219 note->instrument + 1);
1220 } 1220 }
1221 } 1221 }
1222 1222
1223 // Convert certain effects 1223 // Convert certain effects
1224 char effect; 1224 char effect;
1225 JMPGETEFFECT(effect, n->effect); 1225 JMPGETEFFECT(effect, note->effect);
1226 switch (effect) 1226 switch (effect)
1227 { 1227 {
1228 case 'C': // Cxx = Set volume 1228 case 'C': // Cxx = Set volume
1229 if (n->volume == jsetNotSet) 1229 if (note->volume == jsetNotSet)
1230 { 1230 {
1231 n->volume = n->param; 1231 note->volume = note->param;
1232 n->effect = jsetNotSet; 1232 note->effect = jsetNotSet;
1233 n->param = jsetNotSet; 1233 note->param = jsetNotSet;
1234 } 1234 }
1235 break; 1235 break;
1236 } 1236 }
1237 } 1237 }
1238 } 1238 }
1240 // 1240 //
1241 // Remap orders list 1241 // Remap orders list
1242 // 1242 //
1243 dmMsg(1, "Remapping orders list.\n"); 1243 dmMsg(1, "Remapping orders list.\n");
1244 nunused = 0; 1244 nunused = 0;
1245 for (int i = 0; i < m->norders; i++) 1245 for (int nord = 0; nord < src->norders; nord++)
1246 { 1246 {
1247 int map = mapPatterns[m->orderList[i]]; 1247 int map = mapPatterns[src->orderList[nord]];
1248 if (map != m->orderList[i]) 1248 if (map != src->orderList[nord])
1249 { 1249 {
1250 dmPrint(2, "%02x -> %02x : ", m->orderList[i], map); 1250 dmPrint(2, "%02x -> %02x : ", src->orderList[nord], map);
1251 nunused++; 1251 nunused++;
1252 } 1252 }
1253 r->orderList[i] = map; 1253 dst->orderList[nord] = map;
1254 } 1254 }
1255 if (nunused) 1255 if (nunused)
1256 dmPrint(2, "\n"); 1256 dmPrint(2, "\n");
1257 1257
1258 // 1258 //
1259 // Do final pass on patterns to remove unused channels 1259 // Do final pass on patterns to remove unused channels
1260 // 1260 //
1261 for (int i = 0; i < r->npatterns; i++) 1261 for (int npat = 0; npat < dst->npatterns; npat++)
1262 { 1262 {
1263 JSSPattern *p = r->patterns[i]; 1263 JSSPattern *pat = dst->patterns[npat];
1264 1264
1265 jssScanPattern(r, p, i, NULL, p->used); 1265 jssScanPattern(dst, pat, npat, NULL, pat->used);
1266 1266
1267 p->nmap = 0; 1267 pat->nmap = 0;
1268 for (int i = 0; i < r->nchannels; i++) 1268 for (int nchn = 0; nchn < dst->nchannels; nchn++)
1269 { 1269 {
1270 if (p->used[i]) 1270 if (pat->used[nchn])
1271 p->map[p->nmap++] = i; 1271 pat->map[pat->nmap++] = nchn;
1272 } 1272 }
1273 1273
1274 if (p->nmap != p->nchannels) 1274 if (pat->nmap != pat->nchannels)
1275 { 1275 {
1276 dmMsg(2, "Pattern %d: %d/%d used channels (%d unused).\n", 1276 dmMsg(2, "Pattern %d: %d/%d used channels (%d unused).\n",
1277 i, p->nchannels - p->nmap, p->nchannels, p->nmap); 1277 npat, pat->nchannels - pat->nmap, pat->nchannels, pat->nmap);
1278 } 1278 }
1279 } 1279 }
1280 1280
1281 return r; 1281 return dst;
1282 } 1282 }
1283 1283
1284 1284
1285 int main(int argc, char *argv[]) 1285 int main(int argc, char *argv[])
1286 { 1286 {
1287 DMResource *inFile = NULL; 1287 DMResource *inFile = NULL;
1288 FILE *outFile = NULL; 1288 FILE *outFile = NULL;
1289 JSSModule *sm = NULL, *dm = NULL; 1289 JSSModule *src = NULL, *dst = NULL;
1290 int res = DMERR_OK; 1290 int res = DMERR_OK;
1291 1291
1292 dmInitProg("xm2jss", "XM to JSSMOD converter", "0.8", NULL, NULL); 1292 dmInitProg("xm2jss", "XM to JSSMOD converter", "0.8", NULL, NULL);
1293 dmVerbosity = 0; 1293 dmVerbosity = 0;
1294 1294
1316 // Initialize miniJSS 1316 // Initialize miniJSS
1317 jssInit(); 1317 jssInit();
1318 1318
1319 // Read file 1319 // Read file
1320 dmMsg(1, "Reading XM-format file ...\n"); 1320 dmMsg(1, "Reading XM-format file ...\n");
1321 res = jssLoadXM(inFile, &sm, FALSE); 1321 res = jssLoadXM(inFile, &src, FALSE);
1322 dmf_close(inFile); 1322 dmf_close(inFile);
1323 if (res != 0) 1323 if (res != 0)
1324 { 1324 {
1325 dmErrorMsg("Error while loading XM file (%d), ", res); 1325 dmErrorMsg("Error while loading XM file (%d), ", res);
1326 if (optIgnoreErrors) 1326 if (optIgnoreErrors)
1338 1338
1339 // Remove samples 1339 // Remove samples
1340 if (optStripSamples) 1340 if (optStripSamples)
1341 { 1341 {
1342 dmMsg(1, "Stripping samples...\n"); 1342 dmMsg(1, "Stripping samples...\n");
1343 for (int i = 0; i < sm->ninstruments; i++) 1343 for (int i = 0; i < src->ninstruments; i++)
1344 { 1344 {
1345 dmFree(sm->instruments[i]->data); 1345 dmFree(src->instruments[i]->data);
1346 sm->instruments[i]->data = NULL; 1346 src->instruments[i]->data = NULL;
1347 } 1347 }
1348 } 1348 }
1349 1349
1350 // Remove instruments 1350 // Remove instruments
1351 if (optStripInstr) 1351 if (optStripInstr)
1352 { 1352 {
1353 dmMsg(1, "Stripping instruments...\n"); 1353 dmMsg(1, "Stripping instruments...\n");
1354 for (int i = 0; i < sm->ninstruments; i++) 1354 for (int i = 0; i < src->ninstruments; i++)
1355 { 1355 {
1356 dmFree(sm->instruments[i]); 1356 dmFree(src->instruments[i]);
1357 sm->instruments[i] = NULL; 1357 src->instruments[i] = NULL;
1358 } 1358 }
1359 sm->ninstruments = 0; 1359 src->ninstruments = 0;
1360 } 1360 }
1361 1361
1362 // Remove ext.instruments 1362 // Remove ext.instruments
1363 if (optStripExtInstr) 1363 if (optStripExtInstr)
1364 { 1364 {
1365 int i;
1366
1367 dmMsg(1, "Stripping ext.instruments...\n"); 1365 dmMsg(1, "Stripping ext.instruments...\n");
1368 for (i = 0; i < sm->nextInstruments; i++) 1366 for (int i = 0; i < src->nextInstruments; i++)
1369 { 1367 {
1370 dmFree(sm->extInstruments[i]); 1368 dmFree(src->extInstruments[i]);
1371 sm->extInstruments[i] = NULL; 1369 src->extInstruments[i] = NULL;
1372 } 1370 }
1373 sm->nextInstruments = 0; 1371 src->nextInstruments = 0;
1374 } 1372 }
1375 1373
1376 // Run the optimization procedure 1374 // Run the optimization procedure
1377 if (optOptimize) 1375 if (optOptimize)
1378 { 1376 {
1379 dmMsg(1, "Optimizing module data...\n"); 1377 dmMsg(1, "Optimizing module data...\n");
1380 dm = jssOptimizeModule(sm); 1378 dst = jssOptimizeModule(src);
1381 } 1379 }
1382 else 1380 else
1383 dm = sm; 1381 dst = src;
1384 1382
1385 // Write output file 1383 // Write output file
1386 if ((outFile = fopen(optOutFilename, "wb")) == NULL) 1384 if ((outFile = fopen(optOutFilename, "wb")) == NULL)
1387 { 1385 {
1388 int err = dmGetErrno(); 1386 res = dmGetErrno();
1389 dmErrorMsg("Error creating output file '%s', %d: %s\n", 1387 dmErrorMsg("Error creating output file '%s': %s\n",
1390 optOutFilename, err, dmErrorStr(err)); 1388 optOutFilename, dmErrorStr(res));
1391 return 1; 1389 goto out;
1392 } 1390 }
1393 1391
1394 dmMsg(1, "Writing JSSMOD-format file [patMode=0x%04x, samp8=0x%02x, samp16=0x%02x]\n", 1392 dmMsg(1, "Writing JSSMOD-format file [patMode=0x%04x, samp8=0x%02x, samp16=0x%02x]\n",
1395 optPatternMode, optSampMode8, optSampMode16); 1393 optPatternMode, optSampMode8, optSampMode16);
1396 1394
1397 res = jssSaveJSSMOD(outFile, dm, optPatternMode, optSampMode8, optSampMode16); 1395 res = jssSaveJSSMOD(outFile, dst, optPatternMode, optSampMode8, optSampMode16);
1398 1396
1399 fclose(outFile); 1397 fclose(outFile);
1400 1398
1401 if (res != 0) 1399 if (res != 0)
1402 { 1400 {
1409 { 1407 {
1410 dmMsg(1, "Conversion complete.\n"); 1408 dmMsg(1, "Conversion complete.\n");
1411 } 1409 }
1412 1410
1413 out: 1411 out:
1414 jssFreeModule(sm); 1412 jssFreeModule(src);
1415 dmFree(dm); 1413 dmFree(dst);
1416 1414
1417 return res; 1415 return res;
1418 } 1416 }