History

Big code change, read description

1) Don't calculate big LUTs for mixer deltas on init (was just a waste of RAM) 2) The mixer now uses a 64-bit division to calculate max number of safe samples to mix (branchless), instead of using a big hackish LUT for DIV->MUL 3) Module and sample loaders have been refactored so that it's much simpler to write new loaders (or modify the old ones) 4) Added support for importing DIGI Booster (non-Pro) modules 5) Added support for importing 8-channel StarTrekker modules 6) Updated help text 7) Some more minor code change 8) Updated the Visual Studio project and make scripts to include the new loaders * Sorry for not making individual commits for all the changes, but at this point it was simply too difficult for me to do so!

Olav Sørensen committed 5 years ago

Commit 12f28da1 parent 2c1dbb237 files · +6956 −6838Browse files

Showing the changes to src/ft2_module_loader.c (1 of 37 files). Show all

Unified · Split

src/ft2_module_loader.c+248−2315
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 #include <unistd.h>
1111 #endif
1212 #include "ft2_header.h"
13−#include "ft2_config.h"
1413 #include "ft2_scopes.h"
1514 #include "ft2_trim.h"
1615 #include "ft2_inst_ed.h"
@@ -24,1857 +23,206 @@ · 7 unmodified lines
2423 #include "ft2_midi.h"
2524 #include "ft2_events.h"
2625 #include "ft2_video.h"
27−#include "ft2_tables.h"
2826 #include "ft2_structs.h"
27+#include "ft2_sysreqs.h"
2928
30−/* This is a *HUGE* mess!
31−** I hope you never have to modify it, and you probably shouldn't either.
32−** You will experience a lot of headaches if you dig into this file...
33−** If something looks to be wrong, it's probably right!
34−**
35−** The actual module load routines are ported from FT2 and slightly modified.
36−*/
29+bool loadDIGI(FILE *f, uint32_t filesize);
30+bool loadMOD(FILE *f, uint32_t filesize);
31+bool loadS3M(FILE *f, uint32_t filesize);
32+bool loadSTK(FILE *f, uint32_t filesize);
33+bool loadSTM(FILE *f, uint32_t filesize);
34+bool loadXM(FILE *f, uint32_t filesize);
3735
3836 enum
3937 {
40− FORMAT_NONE = 0,
41− FORMAT_XM = 1,
42− FORMAT_MOD = 2,
43− FORMAT_S3M = 3,
44− FORMAT_STM = 4
38+ FORMAT_UNKNOWN = 0,
39+ FORMAT_POSSIBLY_STK = 1,
40+ FORMAT_XM = 2,
41+ FORMAT_MOD = 3,
42+ FORMAT_S3M = 4,
43+ FORMAT_STM = 5,
44+ FORMAT_DIGI = 6
4545 };
4646
47−// .MOD types
48−enum
49−{
50− FORMAT_MK, // ProTracker or compatible
51− FORMAT_FLT, // StarTrekker (4-channel modules only)
52− FORMAT_FT2, // FT2 (or other trackers, multichannel)
53− FORMAT_STK, // The Ultimate SoundTracker (15 samples)
54− FORMAT_NT, // NoiseTracker
55− FORMAT_HMNT, // His Master's NoiseTracker (special one)
56−
57− FORMAT_UNKNOWN // may be The Ultimate Soundtracker (set to FORMAT_STK later)
58−};
59−
60−// DO NOT TOUCH THESE STRUCTS!
61−
62−#ifdef _MSC_VER
63−#pragma pack(push)
64−#pragma pack(1)
65−#endif
66−typedef struct songSTMinstrHeaderTyp_t
67−{
68− char name[12];
69− uint8_t nul, insDisk;
70− uint16_t reserved1, len, repS, repE;
71− uint8_t vol, reserved2;
72− uint16_t rate;
73− int32_t reserved3;
74− uint16_t paraLen;
75−}
76−#ifdef __GNUC__
77−__attribute__ ((packed))
78−#endif
79−songSTMinstrHeaderTyp;
80−
81−typedef struct songSTMHeaderTyp_t
82−{
83− char name[20], sig[8];
84− uint8_t id1a, typ;
85− uint8_t verMajor, verMinor;
86− uint8_t tempo, ap, vol, reserved[13];
87− songSTMinstrHeaderTyp instr[31];
88− uint8_t songTab[128];
89−}
90−#ifdef __GNUC__
91−__attribute__ ((packed))
92−#endif
93−songSTMHeaderTyp;
94−
95−typedef struct songS3MinstrHeaderTyp_t
96−{
97− uint8_t typ;
98− char dosName[12];
99− uint8_t memSegH;
100− uint16_t memSeg;
101− int32_t len, repS, repE;
102− uint8_t vol, dsk, pack, flags;
103− int32_t c2Spd, res1;
104− uint16_t gusPos;
105− uint8_t res2[6];
106− char name[28], id[4];
107−}
108−#ifdef __GNUC__
109−__attribute__ ((packed))
110−#endif
111−songS3MinstrHeaderTyp;
112−
113−typedef struct songS3MHeaderTyp_t
114−{
115− char name[28];
116− uint8_t id1a, typ;
117− uint16_t res1;
118− int16_t songTabLen, antInstr, antPatt;
119− uint16_t flags, trackerID, ver;
120− char id[4];
121− uint8_t globalVol, defSpeed, defTempo, masterVol, res2[12], chanType[32];
122−}
123−#ifdef __GNUC__
124−__attribute__ ((packed))
125−#endif
126−songS3MHeaderTyp;
127−#ifdef _MSC_VER
128−#pragma pack(pop)
129−#endif
130−
131−static volatile uint8_t loadedFormat;
132−static volatile bool linearFreqTable, musicIsLoading, moduleLoaded, moduleFailedToLoad;
133−static uint8_t oldPlayMode, pattBuff[12288], packedPattData[65536];
134−static const uint8_t stmEff[16] = { 0, 0, 11, 0, 10, 2, 1, 3, 4, 7, 0, 5 ,6, 0, 0, 0 };
135−static SDL_Thread *thread;
136−
137−// these temporarily read to, then copied to real struct if load was OK (should not need to be volatile'd)
138−static int16_t pattLensTmp[MAX_PATTERNS];
139−static uint32_t extraSampleLengths[32-MAX_SMP_PER_INST]; // ModPlug Tracker & OpenMPT supports up to 32 samples per instrument in .XM
140−static tonTyp *pattTmp[MAX_PATTERNS];
141−static instrTyp *instrTmp[1+256];
142−static songTyp songTmp;
143−
144−static void setupLoadedModule(void);
145−static void freeTmpModule(void);
146−static bool loadInstrHeader(FILE *f, uint16_t i, bool externalThreadFlag);
147−static bool loadInstrSample(FILE *f, uint16_t i, bool externalThreadFlag);
148−void unpackPatt(uint8_t *dst, uint8_t *src, uint16_t len, int32_t antChn);
149−static bool tmpPatternEmpty(uint16_t nr);
150−static bool loadPatterns(FILE *f, uint16_t antPtn, bool externalThreadFlag);
151−
152−void checkSampleRepeat(sampleTyp *s);
153−
154−// ft2_replayer.c
155−extern const char modSig[32][5];
156−
157−static bool allocateTmpInstr(int16_t nr)
158−{
159− if (instrTmp[nr] != NULL)
160− return false; // already allocated
161−
162− instrTyp *p = (instrTyp *)calloc(1, sizeof (instrTyp));
163− if (p == NULL)
164− return false;
165−
166− sampleTyp *s = p->samp;
167− for (int32_t i = 0; i < MAX_SMP_PER_INST; i++, s++)
168− {
169− s->pan = 128;
170− s->vol = 64;
171− }
172−
173− instrTmp[nr] = p;
174− return true;
175−}
176−
177−#define IS_ID(s, b) !strncmp(s, b, 4)
178−
179−static uint8_t getModType(uint8_t *numChannels, const char *id)
180−{
181− uint8_t modFormat = FORMAT_UNKNOWN;
182− *numChannels = 4;
183−
184− if (IS_ID("M.K.", id) || IS_ID("M!K!", id) || IS_ID("NSMS", id) || IS_ID("LARD", id) || IS_ID("PATT", id))
185− {
186− modFormat = FORMAT_MK; // ProTracker or compatible
187− }
188− else if (id[1] == 'C' && id[2] == 'H' && id[3] == 'N')
189− {
190− modFormat = FORMAT_FT2; // FT2 or generic multichannel
191− *numChannels = id[0] - '0';
192− }
193− else if (id[2] == 'C' && (id[3] == 'H' || id[3] == 'N'))
194− {
195− modFormat = FORMAT_FT2; // FT2 or generic multichannel
196− *numChannels = ((id[0] - '0') * 10) + (id[1] - '0');
197− }
198− else if (IS_ID("FLT4", id))
199− {
200− modFormat = FORMAT_FLT; // StarTrekker (4-channel modules only)
201− }
202− else if (IS_ID("N.T.", id))
203− {
204− modFormat = FORMAT_NT; // NoiseTracker
205− }
206− else if (IS_ID("M&K!", id) || IS_ID("FEST", id))
207− {
208− modFormat = FORMAT_HMNT; // His Master's NoiseTracker
209− }
210−
211− return modFormat;
212−}
213−
214−static bool loadMusicMOD(FILE *f, uint32_t fileLength, bool externalThreadFlag)
215−{
216− char ID[16];
217− uint8_t bytes[4], modFormat, numChannels;
218− int16_t i, j, k, ai;
219− uint16_t a, b, period;
220− tonTyp *ton;
221− sampleTyp *s;
222− songMOD31HeaderTyp h_MOD31;
223− songMOD15HeaderTyp h_MOD15;
224− int16_t (*showMsg)(int16_t, const char *, const char *);
225−
226− showMsg = externalThreadFlag ? okBoxThreadSafe : okBox;
227−
228− bool veryLateSTKVerFlag = false; // "DFJ SoundTracker III" nad later
229− bool lateSTKVerFlag = false; // "TJC SoundTracker II" and later
230− bool mightBeSTK = false;
231−
232− memset(&songTmp, 0, sizeof (songTmp));
233− memset(&h_MOD31, 0, sizeof (songMOD31HeaderTyp));
234− memset(&h_MOD15, 0, sizeof (songMOD15HeaderTyp));
235−
236− // start loading MOD
237−
238− loadedFormat = FORMAT_MOD;
239−
240− rewind(f);
241− fread(ID, 1, 16, f);
242− fseek(f, 0x1D, SEEK_SET);
243− fread(bytes, 1, 1, f);
244− rewind(f);
245−
246− // since .mod is the last format tested, check if the file is an .it module (Impulse Tracker)
247− if (!memcmp(ID, "IMPM", 4) && bytes[0] == 0)
248− {
249− showMsg(0, "System message", "Error: Impulse Tracker modules are not supported!");
250− goto modLoadError;
251− }
252−
253− // check if the file to load is a WAV, if so reject it
254− if (!memcmp(ID, "RIFF", 4) && !memcmp(&ID[8], "WAVEfmt", 7))
255− {
256− showMsg(0, "System message", "Error: Can't load a .wav file as a module!");
257− goto modLoadError;
258− }
259−
260− if (fileLength < 1596 || fileLength > 20842494) // minimum and maximum possible size for a supported .mod
261− {
262− showMsg(0, "System message", "Error: This file is either not a module, or is not supported.");
263− goto modLoadError;
264− }
265−
266− if (fread(&h_MOD31, 1, sizeof (h_MOD31), f) != sizeof (h_MOD31))
267− {
268− showMsg(0, "System message", "Error: This file is either not a module, or is not supported.");
269− goto modLoadError;
270− }
271−
272− modFormat = getModType(&numChannels, h_MOD31.sig);
273−
274− if (modFormat == FORMAT_FLT && numChannels == 8)
275− {
276− showMsg(0, "System message", "8-channel Startrekker modules are not supported!");
277− goto modLoadError;
278− }
279−
280− if (modFormat != FORMAT_UNKNOWN)
281− {
282− if (fileLength < sizeof (h_MOD31))
283− {
284− showMsg(0, "System message", "Error: This file is either not a module, or is not supported.");
285− goto modLoadError;
286− }
287−
288− songTmp.antChn = numChannels;
289− songTmp.len = h_MOD31.len;
290− songTmp.repS = h_MOD31.repS;
291− memcpy(songTmp.songTab, h_MOD31.songTab, 128);
292− ai = 31;
293− }
294− else
295− {
296− mightBeSTK = true;
297− if (fileLength < sizeof (h_MOD15))
298− {
299− showMsg(0, "System message", "Error: This file is not a module!");
300− goto modLoadError;
301− }
302−
303− rewind(f);
304− if (fread(&h_MOD15, 1, sizeof (h_MOD15), f) != sizeof (h_MOD15))
305− {
306− showMsg(0, "System message", "Error: This file is either not a module, or is not supported.");
307− goto modLoadError;
308− }
309−
310− songTmp.antChn = numChannels;
311− songTmp.len = h_MOD15.len;
312− songTmp.repS = h_MOD15.repS;
313− memcpy(songTmp.songTab, h_MOD15.songTab, 128);
314− ai = 15;
315− }
316−
317− if (modFormat == FORMAT_MK && songTmp.len == 129)
318− songTmp.len = 127; // fixes a specific copy of beatwave.mod (FIXME: Do we want to keep this digsuting hack?)
319−
320− if (songTmp.antChn == 0 || songTmp.len < 1 || songTmp.len > 128 || (mightBeSTK && songTmp.repS > 220))
321− {
322− showMsg(0, "System message", "Error: This file is either not a module, or is not supported.");
323− goto modLoadError;
324− }
325−
326− for (a = 0; a < ai; a++)
327− {
328− songMODInstrHeaderTyp *smp = &h_MOD31.instr[a];
329−
330− if (modFormat != FORMAT_HMNT) // most of "His Master's Noisetracker" songs have junk sample names, so let's not load them
331− {
332− // trim off spaces at end of name
333− for (i = 21; i >= 0; i--)
334− {
335− if (smp->name[i] == ' ' || smp->name[i] == 0x1A)
336− smp->name[i] = '\0';
337− else
338− break;
339− }
340−
341− memcpy(songTmp.instrName[1+a], smp->name, 22);
342− songTmp.instrName[1+a][22] = '\0';
343− }
344−
345− /* Only late versions of Ultimate SoundTracker could have samples larger than 9999 bytes.
346− ** If found, we know for sure that this is a late STK module.
347− */
348− if (mightBeSTK && 2*SWAP16(smp->len) > 9999)
349− lateSTKVerFlag = true;
350− }
351−
352− songTmp.speed = 125;
353− if (mightBeSTK)
354− {
355− /* If we're still here at this point and the mightBeSTK flag is set,
356− ** then it's most likely a proper The Ultimate SoundTracker (STK/UST) module.
357− */
358− modFormat = FORMAT_STK;
359−
360− if (songTmp.repS == 0)
361− songTmp.repS = 120;
362−
363− // jjk55.mod by Jesper Kyd has a bogus STK tempo value that should be ignored (hackish!)
364− if (!strcmp("jjk55", h_MOD31.name))
365− songTmp.repS = 120;
366−
367− // The "restart pos" field in STK is the inital tempo (must be converted to BPM first)
368− if (songTmp.repS != 120) // 120 is a special case and means 50Hz (125BPM)
369− {
370− if (songTmp.repS > 220)
371− songTmp.repS = 220;
372−
373− // convert UST tempo to BPM
374− uint16_t ciaPeriod = (240 - songTmp.repS) * 122;
375− double dHz = 709379.0 / ciaPeriod;
376− int32_t BPM = (int32_t)((dHz * 2.5) + 0.5);
377−
378− songTmp.speed = (uint16_t)BPM;
379− }
380−
381− songTmp.repS = 0;
382− }
383− else if (songTmp.repS >= songTmp.len)
384− {
385− songTmp.repS = 0;
386− }
387−
388− // trim off spaces at end of name
389− for (i = 19; i >= 0; i--)
390− {
391− if (h_MOD31.name[i] == ' ' || h_MOD31.name[i] == 0x1A)
392− h_MOD31.name[i] = '\0';
393− else
394− break;
395− }
396−
397− memcpy(songTmp.name, h_MOD31.name, 20);
398− songTmp.name[20] = '\0';
399−
400− // count number of patterns
401− b = 0;
402− for (a = 0; a < 128; a++)
403− {
404− if (songTmp.songTab[a] > b)
405− b = songTmp.songTab[a];
406− }
407− b++;
408−
409− for (a = 0; a < b; a++)
410− {
411− pattTmp[a] = (tonTyp *)calloc((MAX_PATT_LEN * TRACK_WIDTH) + 16, 1);
412− if (pattTmp[a] == NULL)
413− {
414− showMsg(0, "System message", "Not enough memory!");
415− goto modLoadError;
416− }
417−
418− pattLensTmp[a] = 64;
419− for (j = 0; j < 64; j++)
420− {
421− for (k = 0; k < songTmp.antChn; k++)
422− {
423− ton = &pattTmp[a][(j * MAX_VOICES) + k];
424−
425− if (fread(bytes, 1, 4, f) != 4)
426− {
427− showMsg(0, "System message", "Error: This file is either not a module, or is not supported.");
428− goto modLoadError;
429− }
430−
431− // period to note
432− period = ((bytes[0] & 0x0F) << 8) | bytes[1];
433− for (i = 0; i < 8*12; i++)
434− {
435− if (period >= amigaPeriod[i])
436− {
437− ton->ton = (uint8_t)i + 1;
438− break;
439− }
440− }
441−
442− ton->instr = (bytes[0] & 0xF0) | (bytes[2] >> 4);
443− ton->effTyp = bytes[2] & 0x0F;
444− ton->eff = bytes[3];
445−
446− if (modFormat == FORMAT_STK)
447− {
448− if (ton->effTyp == 0xC || ton->effTyp == 0xD || ton->effTyp == 0xE)
449− {
450− // "TJC SoundTracker II" and later
451− lateSTKVerFlag = true;
452− }
453−
454− if (ton->effTyp == 0xF)
455− {
456− // "DFJ SoundTracker III" and later
457− lateSTKVerFlag = true;
458− veryLateSTKVerFlag = true;
459− }
460− }
461−
462− if (ton->effTyp == 0xC)
463− {
464− if (ton->eff > 64)
465− ton->eff = 64;
466− }
467− else if (ton->effTyp == 0x1)
468− {
469− if (ton->eff == 0)
470− ton->effTyp = 0;
471− }
472− else if (ton->effTyp == 0x2)
473− {
474− if (ton->eff == 0)
475− ton->effTyp = 0;
476− }
477− else if (ton->effTyp == 0x5)
478− {
479− if (ton->eff == 0)
480− ton->effTyp = 0x3;
481− }
482− else if (ton->effTyp == 0x6)
483− {
484− if (ton->eff == 0)
485− ton->effTyp = 0x4;
486− }
487− else if (ton->effTyp == 0xA)
488− {
489− if (ton->eff == 0)
490− ton->effTyp = 0;
491− }
492− else if (ton->effTyp == 0xE)
493− {
494− // check if certain E commands are empty
495− if (ton->eff == 0x10 || ton->eff == 0x20 || ton->eff == 0xA0 || ton->eff == 0xB0)
496− {
497− ton->effTyp = 0;
498− ton->eff = 0;
499− }
500− }
501− }
502− }
503−
504− if (tmpPatternEmpty(a))
505− {
506− if (pattTmp[a] != NULL)
507− {
508− free(pattTmp[a]);
509− pattTmp[a] = NULL;
510− }
511− }
512− }
513−
514− // pattern command conversion for non-PT formats
515− if (modFormat == FORMAT_STK || modFormat == FORMAT_NT || modFormat == FORMAT_HMNT || modFormat == FORMAT_FLT)
516− {
517− for (a = 0; a < b; a++)
518− {
519− if (pattTmp[a] == NULL)
520− continue;
521−
522− for (j = 0; j < 64; j++)
523− {
524− for (k = 0; k < songTmp.antChn; k++)
525− {
526− ton = &pattTmp[a][(j * MAX_VOICES) + k];
527−
528− if (modFormat == FORMAT_NT || modFormat == FORMAT_HMNT)
529− {
530− // any Dxx == D00 in NT/HMNT
531− if (ton->effTyp == 0xD)
532− ton->eff = 0;
533−
534− // effect F with param 0x00 does nothing in NT/HMNT
535− if (ton->effTyp == 0xF && ton->eff == 0)
536− ton->effTyp = 0;
537− }
538− else if (modFormat == FORMAT_FLT) // Startrekker
539− {
540− if (ton->effTyp == 0xE) // remove unsupported "assembly macros" command
541− {
542− ton->effTyp = 0;
543− ton->eff = 0;
544− }
545−
546− // Startrekker is always in vblank mode, and limits speed to 0x1F
547− if (ton->effTyp == 0xF && ton->eff > 0x1F)
548− ton->eff = 0x1F;
549− }
550− else if (modFormat == FORMAT_STK)
551− {
552− // convert STK effects to PT effects
553−
554− if (!lateSTKVerFlag)
555− {
556− // old SoundTracker 1.x commands
557−
558− if (ton->effTyp == 1)
559− {
560− // arpeggio
561− ton->effTyp = 0;
562− }
563− else if (ton->effTyp == 2)
564− {
565− // pitch slide
566− if (ton->eff & 0xF0)
567− {
568− // pitch slide down
569− ton->effTyp = 2;
570− ton->eff >>= 4;
571− }
572− else if (ton->eff & 0x0F)
573− {
574− // pitch slide up
575− ton->effTyp = 1;
576− }
577− }
578− }
579− else
580− {
581− // "DFJ SoundTracker II" or later
582−
583− if (ton->effTyp == 0xD)
584− {
585− if (veryLateSTKVerFlag) // "DFJ SoundTracker III" or later
586− {
587− // pattern break w/ no param (param must be cleared to fix some songs)
588− ton->eff = 0;
589− }
590− else
591− {
592− // volume slide
593− ton->effTyp = 0xA;
594− }
595− }
596− }
597−
598− // effect F with param 0x00 does nothing in UST/STK (I think?)
599− if (ton->effTyp == 0xF && ton->eff == 0)
600− ton->effTyp = 0;
601− }
602− }
603− }
604− }
605− }
606−
607− for (a = 0; a < ai; a++)
608− {
609− if (h_MOD31.instr[a].len == 0)
610− continue;
611−
612− if (!allocateTmpInstr(1+a))
613− {
614− showMsg(0, "System message", "Not enough memory!");
615− goto modLoadError;
616− }
617−
618− setNoEnvelope(instrTmp[1+a]);
619−
620− s = &instrTmp[1+a]->samp[0];
621−
622− s->len = 2 * SWAP16(h_MOD31.instr[a].len);
623−
624− if (modFormat != FORMAT_HMNT) // most of "His Master's Noisetracker" songs have junk sample names, so let's not load them
625− memcpy(s->name, songTmp.instrName[1+a], 22);
626−
627− if (modFormat == FORMAT_HMNT) // finetune in "His Master's NoiseTracker" is different
628− h_MOD31.instr[a].fine = (uint8_t)((-h_MOD31.instr[a].fine & 0x1F) >> 1); // one more bit of precision, + inverted
629−
630− if (modFormat != FORMAT_STK)
631− s->fine = 8 * ((2 * ((h_MOD31.instr[a].fine & 0xF) ^ 8)) - 16);
632−
633− s->pan = 128;
634−
635− s->vol = h_MOD31.instr[a].vol;
636− if (s->vol > 64)
637− s->vol = 64;
638−
639− s->repS = 2 * SWAP16(h_MOD31.instr[a].repS);
640− s->repL = 2 * SWAP16(h_MOD31.instr[a].repL);
641−
642− if (s->repL < 2)
643− s->repL = 2;
644−
645− // in The Ultimate SoundTracker, sample loop start is in bytes, not words
646− if (modFormat == FORMAT_STK)
647− s->repS >>= 1;
648−
649− // fix for poorly converted STK (< v2.5) -> PT/NT modules (FIXME: Worth keeping or not?)
650− if (modFormat != FORMAT_STK && s->repL > 2 && s->repS+s->repL > s->len)
651− {
652− if ((s->repS>>1)+s->repL <= s->len)
653− s->repS >>= 1;
654− }
655−
656− // fix overflown loop
657− if (s->repS+s->repL > s->len)
658− {
659− if (s->repS >= s->len)
660− {
661− s->repS = 0;
662− s->repL = 0;
663− }
664− else
665− {
666− s->repL = s->len - s->repS;
667− }
668− }
669−
670− if (s->repS+s->repL > 2)
671− s->typ = 1; // enable loop
672−
673− /* For Ultimate SoundTracker modules, only the loop area of a looped sample is played.
674− ** Skip loading of eventual data present before loop start.
675− */
676− if (modFormat == FORMAT_STK && s->repS > 0 && s->repL < s->len)
677− {
678− s->len -= s->repS;
679− fseek(f, s->repS, SEEK_CUR);
680− s->repS = 0;
681− }
682−
683− s->pek = NULL;
684− s->origPek = (int8_t *)malloc(s->len + LOOP_FIX_LEN);
685− if (s->origPek == NULL)
686− {
687− showMsg(0, "System message", "Not enough memory!");
688− goto modLoadError;
689− }
690−
691− s->pek = s->origPek + SMP_DAT_OFFSET;
692−
693− int32_t bytesRead = (int32_t)fread(s->pek, 1, s->len, f);
694− if (bytesRead < s->len)
695− {
696− int32_t bytesToClear = s->len - bytesRead;
697− memset(&s->pek[bytesRead], 0, bytesToClear);
698− }
699−
700− // clear repL and repS on non-looping samples...
701− if (s->typ == 0)
702− {
703− s->repL = 0;
704− s->repS = 0;
705− }
706−
707− fixSample(s);
708− }
709−
710− fclose(f);
711−
712− songTmp.initialTempo = songTmp.tempo = 6;
713−
714− moduleLoaded = true;
715− return true;
716−
717−modLoadError:
718− fclose(f);
719− freeTmpModule();
720− moduleFailedToLoad = true;
721− return false;
722−}
723−
724−static uint8_t stmTempoToBPM(uint8_t tempo) // ported from original ST2.3 replayer code
725−{
726− const uint8_t slowdowns[16] = { 140, 50, 25, 15, 10, 7, 6, 4, 3, 3, 2, 2, 2, 2, 1, 1 };
727− uint16_t hz = 50;
728−
729− hz -= ((slowdowns[tempo >> 4] * (tempo & 15)) >> 4); // can and will underflow
730−
731− const uint32_t bpm = (hz << 1) + (hz >> 1); // BPM = hz * 2.5
732− return (uint8_t)CLAMP(bpm, 32, 255); // result can be slightly off, but close enough...
733−}
734−
735−static bool loadMusicSTM(FILE *f, uint32_t fileLength, bool externalThreadFlag)
736−{
737− uint8_t typ, tempo;
738− int16_t i, j, k, ap, tmp;
739− uint16_t a;
740− tonTyp *ton;
741− sampleTyp *s;
742− songSTMHeaderTyp h_STM;
743− int16_t (*showMsg)(int16_t, const char *, const char *);
744−
745− showMsg = externalThreadFlag ? okBoxThreadSafe : okBox;
746−
747− rewind(f);
748−
749− // start loading STM
750−
751− if (fread(&h_STM, 1, sizeof (h_STM), f) != sizeof (h_STM))
752− return loadMusicMOD(f, fileLength, externalThreadFlag); // file is not a .stm, try to load as .mod
753−
754− if (memcmp(h_STM.sig, "!Scream!", 8) && memcmp(h_STM.sig, "BMOD2STM", 8) &&
755− memcmp(h_STM.sig, "WUZAMOD!", 8) && memcmp(h_STM.sig, "SWavePro", 8))
756− {
757− return loadMusicMOD(f, fileLength, externalThreadFlag); // file is not a .stm, try to load as .mod
758− }
759−
760− loadedFormat = FORMAT_STM;
761−
762− if (h_STM.verMinor == 0 || h_STM.typ != 2)
763− {
764− showMsg(0, "System message", "Error loading .stm: Incompatible module!");
765− goto stmLoadError;
766− }
767−
768− songTmp.antChn = 4;
769− memcpy(songTmp.songTab, h_STM.songTab, 128);
770−
771− i = 0;
772− while (i < 128 && songTmp.songTab[i] < 99) i++;
773− songTmp.len = i + (i == 0);
774−
775− if (songTmp.len < 255)
776− memset(&songTmp.songTab[songTmp.len], 0, 256 - songTmp.len);
777−
778− // trim off spaces at end of name
779− for (i = 19; i >= 0; i--)
780− {
781− if (h_STM.name[i] == ' ' || h_STM.name[i] == 0x1A)
782− h_STM.name[i] = '\0';
783− else
784− break;
785− }
786−
787− memcpy(songTmp.name, h_STM.name, 20);
788− songTmp.name[20] = '\0';
789−
790− tempo = h_STM.tempo;
791− if (h_STM.verMinor < 21)
792− tempo = ((tempo / 10) << 4) + (tempo % 10);
793−
794− if (tempo == 0)
795− tempo = 96;
796−
797− songTmp.initialTempo = songTmp.tempo = CLAMP(h_STM.tempo >> 4, 1, 31);
798− songTmp.speed = stmTempoToBPM(tempo);
799−
800− if (h_STM.verMinor > 10)
801− songTmp.globVol = MIN(h_STM.vol, 64);
802−
803− ap = h_STM.ap;
804− for (i = 0; i < ap; i++)
805− {
806− pattTmp[i] = (tonTyp *)calloc((MAX_PATT_LEN * TRACK_WIDTH) + 16, 1);
807− if (pattTmp[i] == NULL)
808− {
809− showMsg(0, "System message", "Not enough memory!");
810− goto stmLoadError;
811− }
812−
813− pattLensTmp[i] = 64;
814− if (fread(pattBuff, 64 * 4 * 4, 1, f) != 1)
815− {
816− showMsg(0, "System message", "General I/O error during loading!");
817− goto stmLoadError;
818− }
819−
820− a = 0;
821− for (j = 0; j < 64; j++)
822− {
823− for (k = 0; k < 4; k++)
824− {
825− ton = &pattTmp[i][(j * MAX_VOICES) + k];
826−
827− if (pattBuff[a] == 254)
828− {
829− ton->ton = 97;
830− }
831− else if (pattBuff[a] < 96)
832− {
833− ton->ton = (12 * (pattBuff[a] >> 4)) + (25 + (pattBuff[a] & 0x0F));
834− if (ton->ton > 96)
835− ton->ton = 0;
836− }
837− else
838− {
839− ton->ton = 0;
840− }
841−
842− ton->instr = pattBuff[a + 1] >> 3;
843− typ = (pattBuff[a + 1] & 7) + ((pattBuff[a + 2] & 0xF0) >> 1);
844− if (typ <= 64)
845− ton->vol = typ + 0x10;
846−
847− ton->eff = pattBuff[a + 3];
848−
849− tmp = pattBuff[a + 2] & 0x0F;
850− if (tmp == 1)
851− {
852− ton->effTyp = 15;
853−
854− if (h_STM.verMinor < 21)
855− ton->eff = ((ton->eff / 10) << 4) + (ton->eff % 10);
856−
857− ton->eff >>= 4;
858− }
859− else if (tmp == 3)
860− {
861− ton->effTyp = 13;
862− ton->eff = 0;
863− }
864− else if (tmp == 2 || (tmp >= 4 && tmp <= 12))
865− {
866− ton->effTyp = stmEff[tmp];
867− if (ton->effTyp == 0xA)
868− {
869− if (ton->eff & 0x0F)
870− ton->eff &= 0x0F;
871− else
872− ton->eff &= 0xF0;
873− }
874− }
875− else
876− {
877− ton->eff = 0;
878− }
879−
880− if (ton->effTyp > 35)
881− {
882− ton->effTyp = 0;
883− ton->eff = 0;
884− }
885−
886− a += 4;
887− }
888− }
889−
890− if (tmpPatternEmpty(i))
891− {
892− if (pattTmp[i] != NULL)
893− {
894− free(pattTmp[i]);
895− pattTmp[i] = NULL;
896− }
897− }
898− }
899−
900− for (i = 0; i < 31; i++)
901− {
902− // trim off spaces at end of name
903− for (j = 11; j >= 0; j--)
904− {
905− if (h_STM.instr[i].name[j] == ' ' || h_STM.instr[i].name[j] == 0x1A)
906− h_STM.instr[i].name[j] = '\0';
907− else
908− break;
909− }
910−
911− memset(&songTmp.instrName[1+i], 0, sizeof (songTmp.instrName[1+i]));
912− memcpy(&songTmp.instrName[1+i], h_STM.instr[i].name, 12);
913−
914− if (h_STM.instr[i].len != 0 && h_STM.instr[i].reserved1 != 0)
915− {
916− allocateTmpInstr(1 + i);
917− setNoEnvelope(instrTmp[i]);
918−
919− s = &instrTmp[1+i]->samp[0];
920−
921− s->pek = NULL;
922− s->origPek = (int8_t *)malloc(h_STM.instr[i].len + LOOP_FIX_LEN);
923− if (s->origPek == NULL)
924− {
925− showMsg(0, "System message", "Not enough memory!");
926− goto stmLoadError;
927− }
928−
929− s->pek = s->origPek + SMP_DAT_OFFSET;
930−
931− s->len = h_STM.instr[i].len;
932− tuneSample(s, h_STM.instr[i].rate, false);
933− s->vol = h_STM.instr[i].vol;
934− s->repS = h_STM.instr[i].repS;
935− s->repL = h_STM.instr[i].repE - h_STM.instr[i].repS;
936− s->pan = 128;
937−
938− if (s->repS < s->len && h_STM.instr[i].repE > s->repS && h_STM.instr[i].repE != 0xFFFF)
939− {
940− if (s->repS+s->repL > s->len)
941− s->repL = s->len - s->repS;
942−
943− s->typ = 1; // enable loop
944− }
945− else
946− {
947− s->repS = 0;
948− s->repL = 0;
949− s->typ = 0;
950− }
951−
952− if (s->vol > 64)
953− s->vol = 64;
954−
955− if (fread(s->pek, s->len, 1, f) != 1)
956− {
957− showMsg(0, "System message", "General I/O error during loading! Possibly corrupt module?");
958− goto stmLoadError;
959− }
960−
961− fixSample(s);
962− }
963− }
964−
965− fclose(f);
966−
967− moduleLoaded = true;
968− return true;
969−
970−stmLoadError:
971− fclose(f);
972− freeTmpModule();
973− moduleFailedToLoad = true;
974− return false;
975−}
976−
977−static int8_t countS3MChannels(uint16_t antPtn)
47+// file extensions accepted by Disk Op. in module mode
48+char *supportedModExtensions[] =
97849 {
979− int32_t channels = 0;
980− for (int32_t i = 0; i < antPtn; i++)
981− {
982− if (pattTmp[i] == NULL)
983− continue;
50+ "xm", "ft", "nst", "stk", "mod", "s3m", "stm", "fst", "digi",
98451
985− tonTyp *ton = pattTmp[i];
986− for (int32_t j = 0; j < 64; j++)
987− {
988− for (int32_t k = 0; k < MAX_VOICES; k++, ton++)
989− {
990− if (ton->eff == 0 && ton->effTyp == 0 && ton->instr == 0 && ton->ton == 0 && ton->vol == 0)
991− continue;
52+ "END_OF_LIST" // do NOT move, remove or edit this line!
53+};
99254
993− if (k > channels)
994− channels = k;
995− }
996− }
997− }
998− channels++;
55+// globals for module loaders
56+volatile bool tmpLinearPeriodsFlag;
57+int16_t pattLensTmp[MAX_PATTERNS];
58+tonTyp *pattTmp[MAX_PATTERNS];
59+instrTyp *instrTmp[1+256];
60+songTyp songTmp;
61+// --------------------------
99962
1000− return (int8_t)channels;
1001−}
63+static volatile bool musicIsLoading, moduleLoaded, moduleFailedToLoad;
64+static SDL_Thread *thread;
65+static uint8_t oldPlayMode;
66+static void setupLoadedModule(void);
67+static void freeTmpModule(void);
100268
1003−static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool externalThreadFlag)
69+// Crude module detection routine. These aren't always accurate detections!
70+static int8_t detectModule(FILE *f)
100471 {
1005− int8_t *tmpSmp;
1006− uint8_t ha[2048];
1007− uint8_t alastnfo[32], alastefx[32], alastvibnfo[32], s3mLastGInstr[32];
1008− uint8_t typ;
1009− int16_t ai, ap, ver, ii, kk, tmp;
1010− uint16_t ptnOfs[256];
1011− int32_t i, j, k, len;
1012− tonTyp ton;
1013− sampleTyp *s;
1014− songS3MHeaderTyp h_S3M;
1015− songS3MinstrHeaderTyp h_S3MInstr;
1016− int16_t (*showMsg)(int16_t, const char *, const char *);
1017−
1018− showMsg = externalThreadFlag ? okBoxThreadSafe : okBox;
72+ uint8_t D[256], I[4];
101973
74+ fseek(f, 0, SEEK_END);
75+ uint32_t fileLength = (uint32_t)ftell(f);
102076 rewind(f);
102177
1022− // start loading S3M
1023−
1024− if (fread(&h_S3M, 1, sizeof (h_S3M), f) != sizeof (h_S3M))
1025− return loadMusicSTM(f, dataLength, externalThreadFlag); // not a .s3m, try loading as .stm
1026−
1027− if (memcmp(h_S3M.id, "SCRM", 4))
1028− return loadMusicSTM(f, dataLength, externalThreadFlag); // not a .s3m, try loading as .stm
78+ memset(D, 0, sizeof (D));
79+ fread(D, 1, sizeof (D), f);
80+ fseek(f, 1080, SEEK_SET); // MOD ID
81+ I[0] = I[1] = I[2] = I[3] = 0;
82+ fread(I, 1, 4, f);
83+ rewind(f);
102984
1030− loadedFormat = FORMAT_S3M;
85+ // DIGI Booster (non-Pro)
86+ if (!memcmp("DIGI Booster module", &D[0x00], 19+1) && D[0x19] >= 1 && D[0x19] <= 8)
87+ return FORMAT_DIGI;
103188
1032− if (h_S3M.antInstr > MAX_INST || h_S3M.songTabLen > 256 || h_S3M.antPatt > 256 ||
1033− h_S3M.typ != 16 || h_S3M.ver < 1 || h_S3M.ver > 2)
1034− {
1035− showMsg(0, "System message", "Error loading .s3m: Incompatible module!");
1036− goto s3mLoadError;
1037− }
89+ // Scream Tracker 3 S3M (and compatible trackers)
90+ if (!memcmp("SCRM", &D[0x2C], 4) && D[0x1D] == 16) // XXX: byte=16 in all cases?
91+ return FORMAT_S3M;
103892
1039− memset(songTmp.songTab, 255, sizeof (songTmp.songTab));
1040− if (fread(songTmp.songTab, h_S3M.songTabLen, 1, f) != 1)
93+ // Scream Tracker 2 STM
94+ if ((!memcmp("!Scream!", &D[0x14], 8) || !memcmp("BMOD2STM", &D[0x14], 8) ||
95+ !memcmp("WUZAMOD!", &D[0x14], 8) || !memcmp("SWavePro", &D[0x14], 8)) && D[0x1D] == 2) // XXX: byte=2 for "WUZAMOD!"/"SWavePro" ?
104196 {
1042− showMsg(0, "System message", "General I/O error during loading! Is the file in use?");
1043− goto s3mLoadError;
97+ return FORMAT_STM;
104498 }
104599
1046− songTmp.len = h_S3M.songTabLen;
1047−
1048− // remove pattern separators (254)
1049− k = 0;
1050− j = 0;
1051− for (i = 0; i < songTmp.len; i++)
1052− {
1053− if (songTmp.songTab[i] != 254)
1054− songTmp.songTab[j++] = songTmp.songTab[i];
1055− else
1056− k++;
1057− }
100+ // Generic multi-channel MOD (1..9 channels)
101+ if (isdigit(I[0]) && I[0] != '0' && I[1] == 'C' && I[2] == 'H' && I[3] == 'N') // xCHN
102+ return FORMAT_MOD;
1058103
1059− if (k <= songTmp.len)
1060− songTmp.len -= (uint16_t)k;
1061− else
1062− songTmp.len = 1;
104+ // Generic multi-channel MOD (10..99 channels)
105+ if (isdigit(I[0]) && isdigit(I[1]) && I[0] != '0' && I[2] == 'C' && I[3] == 'H') // xxCH
106+ return FORMAT_MOD;
1063107
1064− for (i = 1; i < songTmp.len; i++)
1065− {
1066− if (songTmp.songTab[i] == 255)
1067− {
1068− songTmp.len = (uint16_t)i;
1069− break;
1070− }
1071− }
108+ // Generic multi-channel MOD (10..99 channels)
109+ if (isdigit(I[0]) && isdigit(I[1]) && I[0] != '0' && I[2] == 'C' && I[3] == 'N') // xxCN (same as xxCH)
110+ return FORMAT_MOD;
1072111
1073− // clear unused song table entries
1074− if (songTmp.len < 255)
1075− memset(&songTmp.songTab[songTmp.len], 0, 255-songTmp.len);
1076−
1077− songTmp.speed = h_S3M.defTempo;
1078− if (songTmp.speed < 32)
1079− songTmp.speed = 32;
1080−
1081− songTmp.tempo = h_S3M.defSpeed;
1082− if (songTmp.tempo == 0)
1083− songTmp.tempo = 6;
1084−
1085− if (songTmp.tempo > 31)
1086− songTmp.tempo = 31;
1087−
1088− songTmp.initialTempo = songTmp.tempo;
1089−
1090− // trim off spaces at end of name
1091− for (i = 19; i >= 0; i--)
1092− {
1093− if (h_S3M.name[i] == ' ' || h_S3M.name[i] == 0x1A)
1094− h_S3M.name[i] = '\0';
1095− else
1096− break;
1097− }
1098−
1099− memcpy(songTmp.name, h_S3M.name, 20);
1100− songTmp.name[20] = '\0';
1101−
1102− ap = h_S3M.antPatt;
1103− ai = h_S3M.antInstr;
1104− ver = h_S3M.ver;
1105−
1106− k = 31;
1107− while (k >= 0 && h_S3M.chanType[k] >= 16) k--;
1108− songTmp.antChn = (k + 2) & 254;
1109−
1110− if (fread(ha, ai + ai, 1, f) != 1)
1111− {
1112− showMsg(0, "System message", "General I/O error during loading! Is the file in use?");
1113− goto s3mLoadError;
1114− }
1115−
1116− if (fread(ptnOfs, ap + ap, 1, f) != 1)
1117− {
1118− showMsg(0, "System message", "General I/O error during loading! Is the file in use?");
1119− goto s3mLoadError;
1120− }
1121−
1122− // *** PATTERNS ***
1123−
1124− k = 0;
1125− for (i = 0; i < ap; i++)
112+ // Generic 4-channel MOD (NoiseTracker/ProTracker or compatible)
113+ if (!memcmp("M.K.", I, 4) || !memcmp("M!K!", I, 4) || !memcmp("NSMS", I, 4) ||
114+ !memcmp("LARD", I, 4) || !memcmp("PATT", I, 4) || !memcmp("PATT", I, 4) ||
115+ !memcmp("FLT4", I, 4) || !memcmp("FLT8", I, 4) || !memcmp("N.T.", I, 4) ||
116+ !memcmp("M&K!", I, 4) || !memcmp("FEST", I, 4))
1126117 {
1127− if (ptnOfs[i] == 0)
1128− continue; // empty pattern
1129−
1130− memset(alastnfo, 0, sizeof (alastnfo));
1131− memset(alastefx, 0, sizeof (alastefx));
1132− memset(alastvibnfo, 0, sizeof (alastvibnfo));
1133− memset(s3mLastGInstr, 0, sizeof (s3mLastGInstr));
1134−
1135− fseek(f, ptnOfs[i] << 4, SEEK_SET);
1136− if (feof(f))
1137− continue;
1138−
1139− if (fread(&j, 2, 1, f) != 1)
1140− {
1141− showMsg(0, "System message", "General I/O error during loading! Is the file in use?");
1142− goto s3mLoadError;
1143− }
1144−
1145− if (j > 0 && j <= 12288)
1146− {
1147− pattTmp[i] = (tonTyp *)calloc((MAX_PATT_LEN * TRACK_WIDTH) + 16, 1);
1148− if (pattTmp[i] == NULL)
1149− {
1150− showMsg(0, "System message", "Not enough memory!");
1151− goto s3mLoadError;
1152− }
1153−
1154− pattLensTmp[i] = 64;
1155− fread(pattBuff, j, 1, f);
1156−
1157− k = 0;
1158− kk = 0;
1159−
1160− while (k < j && kk < 64)
1161− {
1162− typ = pattBuff[k++];
1163−
1164− if (typ == 0)
1165− {
1166− kk++;
1167− }
1168− else
1169− {
1170− ii = typ & 31;
1171−
1172− memset(&ton, 0, sizeof (ton));
1173−
1174− // note and sample
1175− if (typ & 32)
1176− {
1177− ton.ton = pattBuff[k++];
1178− ton.instr = pattBuff[k++];
1179−
1180− if (ton.instr > MAX_INST)
1181− ton.instr = 0;
1182−
1183− if (ton.ton == 254) ton.ton = 97;
1184− else if (ton.ton == 255) ton.ton = 0;
1185− else
1186− {
1187− ton.ton = 1 + (ton.ton & 0xF) + (ton.ton >> 4) * 12;
1188− if (ton.ton > 96)
1189− ton.ton = 0;
1190− }
1191− }
1192−
1193− // volume column
1194− if (typ & 64)
1195− {
1196− ton.vol = pattBuff[k++];
1197−
1198− if (ton.vol <= 64)
1199− ton.vol += 0x10;
1200− else
1201− ton.vol = 0;
1202− }
1203−
1204− // effect
1205− if (typ & 128)
1206− {
1207− ton.effTyp = pattBuff[k++];
1208− ton.eff = pattBuff[k++];
1209−
1210− if (ton.eff > 0)
1211− {
1212− alastnfo[ii] = ton.eff;
1213− if (ton.effTyp == 8 || ton.effTyp == 21)
1214− alastvibnfo[ii] = ton.eff; // H/U
1215− }
1216−
1217− // in ST3, a lot of effects directly share the same memory!
1218− if (ton.eff == 0 && ton.effTyp != 7) // G
1219− {
1220− uint8_t efx = ton.effTyp;
1221− if (efx == 8 || efx == 21) // H/U
1222− ton.eff = alastvibnfo[ii];
1223− else if ((efx >= 4 && efx <= 12) || (efx >= 17 && efx <= 19)) // D/E/F/I/J/K/L/Q/R/S
1224− ton.eff = alastnfo[ii];
1225−
1226− /* If effect data is zero and effect type was the same as last one, clear out
1227− ** data if it's not J or S (those have no memory in the equivalent XM effects).
1228− ** Also goes for extra fine pitch slides and fine volume slides,
1229− ** since they get converted to other effects.
1230− */
1231− if (efx == alastefx[ii] && ton.effTyp != 10 && ton.effTyp != 19) // J/S
1232− {
1233− uint8_t nfo = ton.eff;
1234− bool extraFinePitchSlides = (efx == 5 || efx == 6) && ((nfo & 0xF0) == 0xE0);
1235− bool fineVolSlides = (efx == 4 || efx == 11) &&
1236− ((nfo > 0xF0) || (((nfo & 0xF) == 0xF) && ((nfo & 0xF0) > 0)));
1237−
1238− if (!extraFinePitchSlides && !fineVolSlides)
1239− ton.eff = 0;
1240− }
1241− }
1242−
1243− if (ton.effTyp > 0)
1244− alastefx[ii] = ton.effTyp;
1245−
1246− switch (ton.effTyp)
1247− {
1248− case 1: // A
1249− {
1250− ton.effTyp = 0xF;
1251− if (ton.eff == 0 || ton.eff > 0x1F)
1252− {
1253− ton.effTyp = 0;
1254− ton.eff = 0;
1255− }
1256− }
1257− break;
1258−
1259− case 2: ton.effTyp = 0xB; break; // B
1260− case 3: ton.effTyp = 0xD; break; // C
1261− case 4: // D
1262− {
1263− if (ton.eff > 0xF0) // fine slide up
1264− {
1265− ton.effTyp = 0xE;
1266− ton.eff = 0xB0 | (ton.eff & 0xF);
1267− }
1268− else if ((ton.eff & 0x0F) == 0x0F && (ton.eff & 0xF0) > 0) // fine slide down
1269− {
1270− ton.effTyp = 0xE;
1271− ton.eff = 0xA0 | (ton.eff >> 4);
1272− }
1273− else
1274− {
1275− ton.effTyp = 0xA;
1276− if (ton.eff & 0x0F) // on D/K, last nybble has first priority in ST3
1277− ton.eff &= 0x0F;
1278− }
1279− }
1280− break;
1281−
1282− case 5: // E
1283− case 6: // F
1284− {
1285− if ((ton.eff & 0xF0) >= 0xE0)
1286− {
1287− // convert to fine slide
1288− if ((ton.eff & 0xF0) == 0xE0)
1289− tmp = 0x21;
1290− else
1291− tmp = 0xE;
1292−
1293− ton.eff &= 0x0F;
1294−
1295− if (ton.effTyp == 0x05)
1296− ton.eff |= 0x20;
1297− else
1298− ton.eff |= 0x10;
1299−
1300− ton.effTyp = (uint8_t)tmp;
1301−
1302− if (ton.effTyp == 0x21 && ton.eff == 0)
1303− {
1304− ton.effTyp = 0;
1305− }
1306− }
1307− else
1308− {
1309− // convert to normal 1xx/2xx slide
1310− ton.effTyp = 7 - ton.effTyp;
1311− }
1312− }
1313− break;
1314−
1315− case 7: // G
1316− {
1317− ton.effTyp = 0x03;
1318−
1319− // fix illegal slides (to new instruments)
1320− if (ton.instr != 0 && ton.instr != s3mLastGInstr[ii])
1321− ton.instr = s3mLastGInstr[ii];
1322− }
1323− break;
1324−
1325− case 11: // K
1326− {
1327− if (ton.eff > 0xF0) // fine slide up
1328− {
1329− ton.effTyp = 0xE;
1330− ton.eff = 0xB0 | (ton.eff & 0xF);
1331−
1332− // if volume column is unoccupied, set to vibrato
1333− if (ton.vol == 0)
1334− ton.vol = 0xB0;
1335− }
1336− else if ((ton.eff & 0x0F) == 0x0F && (ton.eff & 0xF0) > 0) // fine slide down
1337− {
1338− ton.effTyp = 0xE;
1339− ton.eff = 0xA0 | (ton.eff >> 4);
1340−
1341− // if volume column is unoccupied, set to vibrato
1342− if (ton.vol == 0)
1343− ton.vol = 0xB0;
1344− }
1345− else
1346− {
1347− ton.effTyp = 0x6;
1348− if (ton.eff & 0x0F) // on D/K, last nybble has first priority in ST3
1349− ton.eff &= 0x0F;
1350− }
1351− }
1352− break;
1353−
1354− case 8: ton.effTyp = 0x04; break; // H
1355− case 9: ton.effTyp = 0x1D; break; // I
1356− case 10: ton.effTyp = 0x00; break; // J
1357− case 12: ton.effTyp = 0x05; break; // L
1358− case 15: ton.effTyp = 0x09; break; // O
1359− case 17: ton.effTyp = 0x1B; break; // Q
1360− case 18: ton.effTyp = 0x07; break; // R
1361−
1362− case 19: // S
1363− {
1364− ton.effTyp = 0xE;
1365− tmp = ton.eff >> 4;
1366− ton.eff &= 0x0F;
1367−
1368− if (tmp == 0x1) ton.eff |= 0x30;
1369− else if (tmp == 0x2) ton.eff |= 0x50;
1370− else if (tmp == 0x3) ton.eff |= 0x40;
1371− else if (tmp == 0x4) ton.eff |= 0x70;
1372− // ignore S8x becuase it's not compatible with FT2 panning
1373− else if (tmp == 0xB) ton.eff |= 0x60;
1374− else if (tmp == 0xC) // Note Cut
1375− {
1376− ton.eff |= 0xC0;
1377− if (ton.eff == 0xC0)
1378− {
1379− // EC0 does nothing in ST3 but cuts voice in FT2, remove effect
1380− ton.effTyp = 0;
1381− ton.eff = 0;
1382− }
1383− }
1384− else if (tmp == 0xD) // Note Delay
1385− {
1386− ton.eff |= 0xD0;
1387− if (ton.ton == 0 || ton.ton == 97)
1388− {
1389− // EDx without a note does nothing in ST3 but retrigs in FT2, remove effect
1390− ton.effTyp = 0;
1391− ton.eff = 0;
1392− }
1393− else if (ton.eff == 0xD0)
1394− {
1395− // ED0 prevents note/smp/vol from updating in ST3, remove everything
1396− ton.ton = 0;
1397− ton.instr = 0;
1398− ton.vol = 0;
1399− ton.effTyp = 0;
1400− ton.eff = 0;
1401− }
1402− }
1403− else if (tmp == 0xE) ton.eff |= 0xE0;
1404− else if (tmp == 0xF) ton.eff |= 0xF0;
1405− else
1406− {
1407− ton.effTyp = 0;
1408− ton.eff = 0;
1409− }
1410− }
1411− break;
1412−
1413− case 20: // T
1414− {
1415− ton.effTyp = 0x0F;
1416− if (ton.eff < 0x21) // Txx with a value lower than 33 (0x21) does nothing in ST3, remove effect
1417− {
1418− ton.effTyp = 0;
1419− ton.eff = 0;
1420− }
1421− }
1422− break;
1423−
1424− case 22: // V
1425− {
1426− ton.effTyp = 0x10;
1427− if (ton.eff > 0x40)
1428− {
1429− // Vxx > 0x40 does nothing in ST3
1430− ton.effTyp = 0;
1431− ton.eff = 0;
1432− }
1433− }
1434− break;
1435−
1436− default:
1437− {
1438− ton.effTyp = 0;
1439− ton.eff = 0;
1440− }
1441− break;
1442− }
1443− }
1444−
1445− if (ton.instr != 0 && ton.effTyp != 0x3)
1446− s3mLastGInstr[ii] = ton.instr;
1447−
1448− if (ton.effTyp > 35)
1449− {
1450− ton.effTyp = 0;
1451− ton.eff = 0;
1452− }
1453−
1454− pattTmp[i][(kk * MAX_VOICES) + ii] = ton;
1455− }
1456− }
1457−
1458− if (tmpPatternEmpty((uint16_t)i))
1459− {
1460− if (pattTmp[i] != NULL)
1461− {
1462− free(pattTmp[i]);
1463− pattTmp[i] = NULL;
1464− }
1465− }
1466− }
118+ return FORMAT_MOD;
1467119 }
1468120
1469− // *** SAMPLES ***
1470−
1471− bool adlibInsWarn = false;
1472−
1473− memcpy(ptnOfs, ha, 512);
1474− for (i = 0; i < ai; i++)
1475− {
1476− fseek(f, ptnOfs[i] << 4, SEEK_SET);
1477−
1478− if (fread(&h_S3MInstr, 1, sizeof (h_S3MInstr), f) != sizeof (h_S3MInstr))
1479− {
1480− showMsg(0, "System message", "Not enough memory!");
1481− goto s3mLoadError;
1482− }
1483−
1484− // trim off spaces at end of name
1485− for (j = 21; j >= 0; j--)
1486− {
1487− if (h_S3MInstr.name[j] == ' ' || h_S3MInstr.name[j] == 0x1A)
1488− h_S3MInstr.name[j] = '\0';
1489− else
1490− break;
1491− }
1492−
1493− memcpy(songTmp.instrName[1+i], h_S3MInstr.name, 22);
1494− songTmp.instrName[1+i][22] = '\0';
1495−
1496− if (h_S3MInstr.typ == 2)
1497− {
1498− adlibInsWarn = true;
1499− }
1500− else if (h_S3MInstr.typ == 1)
1501− {
1502− if ((h_S3MInstr.flags & (255-1-2-4)) != 0 || h_S3MInstr.pack != 0)
1503− {
1504− showMsg(0, "System message", "Error loading .s3m: Incompatible module!");
1505− goto s3mLoadError;
1506− }
1507− else if (h_S3MInstr.memSeg > 0 && h_S3MInstr.len > 0)
1508− {
1509− if (!allocateTmpInstr((int16_t)(1 + i)))
1510− {
1511− showMsg(0, "System message", "Not enough memory!");
1512− goto s3mLoadError;
1513− }
1514−
1515− setNoEnvelope(instrTmp[1 + i]);
1516− s = &instrTmp[1+i]->samp[0];
1517−
1518− len = h_S3MInstr.len;
1519−
1520− bool hasLoop = h_S3MInstr.flags & 1;
1521− bool stereoSample = (h_S3MInstr.flags >> 1) & 1;
1522− bool is16Bit = (h_S3MInstr.flags >> 2) & 1;
1523−
1524− if (is16Bit) // 16-bit
1525− len <<= 1;
1526−
1527− if (stereoSample) // stereo
1528− len <<= 1;
1529−
1530− tmpSmp = (int8_t *)malloc(len + LOOP_FIX_LEN);
1531− if (tmpSmp == NULL)
1532− {
1533− showMsg(0, "System message", "Not enough memory!");
1534− goto s3mLoadError;
1535− }
1536−
1537− int8_t *newPtr = tmpSmp + SMP_DAT_OFFSET;
1538−
1539− memcpy(s->name, h_S3MInstr.name, 21);
1540−
1541− if (h_S3MInstr.c2Spd > 65535) // ST3 (and OpenMPT) does this
1542− h_S3MInstr.c2Spd = 65535;
1543−
1544− tuneSample(s, h_S3MInstr.c2Spd, false);
1545−
1546− s->len = h_S3MInstr.len;
1547− s->vol = h_S3MInstr.vol;
1548− s->repS = h_S3MInstr.repS;
1549− s->repL = h_S3MInstr.repE - h_S3MInstr.repS;
1550−
1551− // non-FT2: fixes "miracle man.s3m"
1552− if ((h_S3MInstr.memSeg<<4)+s->len > (int32_t)dataLength)
1553− s->len = dataLength - (h_S3MInstr.memSeg << 4);
1554−
1555− if (s->repL <= 2 || s->repS+s->repL > s->len)
1556− {
1557− s->repS = 0;
1558− s->repL = 0;
1559− hasLoop = false;
1560− }
1561−
1562− if (s->repL == 0)
1563− hasLoop = false;
1564−
1565− s->typ = hasLoop + (is16Bit << 4);
1566−
1567− if (s->vol > 64)
1568− s->vol = 64;
1569−
1570− s->pan = 128;
1571−
1572− fseek(f, h_S3MInstr.memSeg << 4, SEEK_SET);
1573−
1574− // non-FT2: fixes "miracle man.s3m"
1575− if ((h_S3MInstr.memSeg<<4)+len > (int32_t)dataLength)
1576− len = dataLength - (h_S3MInstr.memSeg << 4);
1577−
1578− if (ver == 1)
1579− {
1580− fseek(f, len, SEEK_CUR); // sample not supported
1581− }
1582− else
1583− {
1584− if (fread(newPtr, len, 1, f) != 1)
1585− {
1586− free(tmpSmp);
1587− showMsg(0, "System message", "General I/O error during loading! Is the file in use?");
1588− goto s3mLoadError;
1589− }
1590−
1591− if (is16Bit)
1592− {
1593− conv16BitSample(newPtr, len, stereoSample);
1594−
1595− s->origPek = tmpSmp;
1596− s->pek = s->origPek + SMP_DAT_OFFSET;
1597−
1598− s->len <<= 1;
1599− s->repS <<= 1;
1600− s->repL <<= 1;
1601− }
1602− else
1603− {
1604− conv8BitSample(newPtr, len, stereoSample);
1605−
1606− s->origPek = tmpSmp;
1607− s->pek = s->origPek + SMP_DAT_OFFSET;
1608− }
1609−
1610− // if stereo sample: reduce memory footprint after sample was downmixed to mono
1611− if (stereoSample)
1612− {
1613− newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN);
1614− if (newPtr != NULL)
1615− {
1616− s->origPek = newPtr;
1617− s->pek = s->origPek + SMP_DAT_OFFSET;
1618− }
1619− }
1620−
1621− fixSample(s);
1622− }
1623− }
1624− }
1625− }
121+ /* Check if the file is a .it module (Impulse Tracker, not supported).
122+ ** Some people may attempt to load .IT files in the FT2 clone, so
123+ ** reject them here instead of accidentally loading them as .STK
124+ */
125+ if (!memcmp("IMPM", D, 4) && D[0x16] == 0)
126+ return FORMAT_UNKNOWN;
1626127
1627− fclose(f);
128+ /* Fasttracker II XM and compatible trackers.
129+ ** Note: This test can falsely be true for STK modules (and non-supported files) where the
130+ ** first 17 bytes start with "Extended Module: ". This is unlikely to happen.
131+ */
132+ if (!memcmp("Extended Module: ", &D[0x00], 17))
133+ return FORMAT_XM;
1628134
1629− songTmp.antChn = countS3MChannels(ap);
135+ /* Lastly, we assume that the file is either a 15-sample STK or an unsupported file.
136+ ** Let's assume it's an STK and do some sanity checks. If they fail, we have an
137+ ** unsupported file.
138+ */
1630139
1631− if (adlibInsWarn)
1632− showMsg(0, "System message", "Warning: The module contains unsupported AdLib instruments!");
140+ // minimum and maximum (?) possible size for a supported STK
141+ if (fileLength < 1624 || fileLength > 984634)
142+ return FORMAT_UNKNOWN;
1633143
1634− if (!(config.dontShowAgainFlags & DONT_SHOW_S3M_LOAD_WARNING_FLAG))
1635− showMsg(6, "System message", "Warning: S3M channel panning is ignored because it's not compatible with FT2.");
144+ // test STK numOrders+BPM for illegal values
145+ fseek(f, 470, SEEK_SET);
146+ D[0] = D[1] = 0;
147+ fread(D, 1, 2, f);
148+ rewind(f);
1636149
1637− moduleLoaded = true;
1638− return true;
150+ if (D[0] >= 0 && D[0] <= 128 && D[1] <= 220)
151+ return FORMAT_POSSIBLY_STK;
1639152
1640−s3mLoadError:
1641− fclose(f);
1642− freeTmpModule();
1643− moduleFailedToLoad = true;
1644− return false;
153+ return FORMAT_UNKNOWN;
1645154 }
1646155
1647−bool doLoadMusic(bool externalThreadFlag)
156+static bool doLoadMusic(bool externalThreadFlag)
1648157 {
1649− char tmpText[128];
1650− int16_t k;
1651− uint16_t i;
1652− uint32_t filelength;
1653− songHeaderTyp h;
1654− FILE *f;
1655− int16_t (*showMsg)(int16_t, const char *, const char *);
1656−
1657− showMsg = externalThreadFlag ? okBoxThreadSafe : okBox;
1658−
1659− linearFreqTable = false;
158+ // setup message box functions
159+ loaderMsgBox = externalThreadFlag ? myLoaderMsgBoxThreadSafe : myLoaderMsgBox;
160+ loaderSysReq = externalThreadFlag ? okBoxThreadSafe : okBox;
1660161
1661162 if (editor.tmpFilenameU == NULL)
1662163 {
1663− showMsg(0, "System message", "Generic memory fault during loading!");
1664− moduleFailedToLoad = true;
1665− return false;
164+ loaderMsgBox("Generic memory fault during loading!");
165+ goto loadError;
1666166 }
1667167
1668− f = UNICHAR_FOPEN(editor.tmpFilenameU, "rb");
168+ FILE *f = UNICHAR_FOPEN(editor.tmpFilenameU, "rb");
1669169 if (f == NULL)
1670170 {
1671− showMsg(0, "System message", "General I/O error during loading! Is the file in use? Does it exist?");
1672− moduleFailedToLoad = true;
1673− return false;
171+ loaderMsgBox("General I/O error during loading! Is the file in use? Does it exist?");
172+ goto loadError;
1674173 }
1675174
175+ int8_t format = detectModule(f);
1676176 fseek(f, 0, SEEK_END);
1677− filelength = ftell(f);
1678− rewind(f);
1679−
1680− // start loading
1681− if (fread(&h, 1, sizeof (h), f) != sizeof (h))
1682− return loadMusicS3M(f, filelength, externalThreadFlag); // not a .xm file, try to load as .s3m
1683−
1684− if (memcmp(h.sig, "Extended Module: ", 17))
1685− return loadMusicS3M(f, filelength, externalThreadFlag); // not a .xm file, try to load as .s3m
1686−
1687− loadedFormat = FORMAT_XM;
1688−
1689− if (h.ver < 0x0102 || h.ver > 0x0104)
1690− {
1691− fclose(f);
1692−
1693− const int32_t major = (h.ver >> 8) & 0x0F;
1694− const int32_t minor = h.ver & 0xFF;
1695−
1696− sprintf(tmpText, "Error loading XM: Unsupported file version (v%01X.%02X).", major, minor);
1697− showMsg(0, "System message", tmpText);
1698−
1699− moduleFailedToLoad = true;
1700− return false;
1701− }
1702−
1703− if (h.len > MAX_ORDERS)
1704− {
1705− showMsg(0, "System message", "Error loading XM: The song has more than 256 orders!");
1706− goto xmLoadError;
1707− }
1708−
1709− if (h.antPtn > MAX_PATTERNS)
1710− {
1711− showMsg(0, "System message", "Error loading XM: The song has more than 256 patterns!");
1712− goto xmLoadError;
1713− }
1714−
1715− if (h.antChn == 0)
1716− {
1717− showMsg(0, "System message", "Error loading XM: This file is corrupt.");
1718− goto xmLoadError;
1719− }
1720−
1721− if (h.antInstrs > 256) // if >128 instruments, we fake-load up to 128 extra instruments and discard them
1722− {
1723− showMsg(0, "System message", "Error loading XM: This file is corrupt.");
1724− goto xmLoadError;
1725− }
1726−
1727− fseek(f, 60 + h.headerSize, SEEK_SET);
1728− if (filelength != 336 && feof(f)) // 336 in length at this point = empty XM
1729− {
1730− showMsg(0, "System message", "Error loading XM: The module is empty!");
1731− goto xmLoadError;
1732− }
1733−
1734− // trim off spaces at end of name
1735− for (k = 19; k >= 0; k--)
1736− {
1737− if (h.name[k] == ' ' || h.name[k] == 0x1A)
1738− h.name[k] = '\0';
1739− else
1740− break;
1741− }
1742−
1743− memcpy(songTmp.name, h.name, 20);
1744− songTmp.name[20] = '\0';
177+ uint32_t filesize = ftell(f);
1745178
1746− songTmp.len = h.len;
1747− songTmp.repS = h.repS;
1748− songTmp.antChn = (uint8_t)h.antChn;
1749− songTmp.speed = h.defSpeed;
1750− songTmp.tempo = h.defTempo;
1751− songTmp.ver = h.ver;
1752− linearFreqTable = h.flags & 1;
1753−
1754− songTmp.speed = CLAMP(songTmp.speed, 1, 999);
1755− songTmp.tempo = CLAMP(songTmp.tempo, 1, 99);
1756−
1757− songTmp.initialTempo = songTmp.tempo;
1758−
1759− if (songTmp.globVol > 64)
1760− songTmp.globVol = 64;
1761−
1762− if (songTmp.len == 0)
1763− songTmp.len = 1; // songTmp.songTab is already empty
1764− else
1765− memcpy(songTmp.songTab, h.songTab, songTmp.len);
1766−
1767− // some strange XMs have the order list padded with 0xFF, remove them!
1768− for (int16_t j = 255; j >= 0; j--)
1769− {
1770− if (songTmp.songTab[j] != 0xFF)
1771− break;
1772−
1773− if (songTmp.len > j)
1774− songTmp.len = j;
1775− }
1776−
1777− // even though XM supports 256 orders, FT2 supports only 255...
1778− if (songTmp.len > 0xFF)
1779− songTmp.len = 0xFF;
1780−
1781− if (songTmp.ver < 0x0104)
1782− {
1783− // XM v1.02 and XM v1.03
1784−
1785− for (i = 1; i <= h.antInstrs; i++)
1786− {
1787− if (!loadInstrHeader(f, i, externalThreadFlag))
1788− goto xmLoadError;
1789− }
1790−
1791− if (!loadPatterns(f, h.antPtn, externalThreadFlag))
1792− goto xmLoadError;
1793−
1794− for (i = 1; i <= h.antInstrs; i++)
1795− {
1796− if (!loadInstrSample(f, i, externalThreadFlag))
1797− goto xmLoadError;
1798− }
1799− }
1800− else
179+ rewind(f);
180+ switch (format)
1801181 {
1802− // XM v1.04 (latest version)
1803−
1804− if (!loadPatterns(f, h.antPtn, externalThreadFlag))
1805− goto xmLoadError;
182+ case FORMAT_XM: moduleLoaded = loadXM(f, filesize); break;
183+ case FORMAT_S3M: moduleLoaded = loadS3M(f, filesize); break;
184+ case FORMAT_STM: moduleLoaded = loadSTM(f, filesize); break;
185+ case FORMAT_MOD: moduleLoaded = loadMOD(f, filesize); break;
186+ case FORMAT_POSSIBLY_STK: moduleLoaded = loadSTK(f, filesize); break;
187+ case FORMAT_DIGI: moduleLoaded = loadDIGI(f, filesize); break;
1806188
1807− for (i = 1; i <= h.antInstrs; i++)
1808− {
1809− if (!loadInstrHeader(f, i, externalThreadFlag))
1810− goto xmLoadError;
1811−
1812− if (!loadInstrSample(f, i, externalThreadFlag))
1813− goto xmLoadError;
1814− }
1815− }
1816−
1817− // if we temporarily loaded more than 128 instruments, clear the extra allocated memory
1818− if (h.antInstrs > MAX_INST)
1819− {
1820− for (i = MAX_INST+1; i <= h.antInstrs; i++)
1821− {
1822− if (instrTmp[i] != NULL)
1823− {
1824− free(instrTmp[i]);
1825− instrTmp[i] = NULL;
1826− }
1827− }
189+ default:
190+ loaderMsgBox("This file is not a supported module!");
191+ break;
1828192 }
1829−
1830193 fclose(f);
1831194
1832− /* We support loading XMs with up to 32 samples per instrument (ModPlug/OpenMPT),
1833− ** but only the first 16 will be loaded. Now make sure we set the number of samples
1834− ** back to max 16 in the headers before loading is done.
1835− */
1836− bool instrHasMoreThan16Samples = false;
1837− for (i = 1; i <= MAX_INST; i++)
1838− {
1839− if (instrTmp[i] != NULL && instrTmp[i]->antSamp > MAX_SMP_PER_INST)
1840− {
1841− instrHasMoreThan16Samples = true;
1842− instrTmp[i]->antSamp = MAX_SMP_PER_INST;
1843− }
1844− }
1845−
1846− if (songTmp.antChn > MAX_VOICES)
1847− {
1848− songTmp.antChn = MAX_VOICES;
1849− showMsg(0, "System message", "Warning: This XM contains >32 channels. The extra channels will be discarded!");
1850− }
1851−
1852− if (h.antInstrs > MAX_INST)
1853− showMsg(0, "System message", "Warning: This XM contains >128 instruments. The extra instruments will be discarded!");
1854−
1855− if (instrHasMoreThan16Samples)
1856− showMsg(0, "System message", "Warning: This XM contains instrument(s) with >16 samples. The extra samples will be discarded!");
195+ if (!moduleLoaded)
196+ goto loadError;
1857197
1858198 moduleLoaded = true;
1859199 return true;
1860200
1861−xmLoadError:
1862− fclose(f);
201+loadError:
1863202 freeTmpModule();
1864203 moduleFailedToLoad = true;
1865204 return false;
1866205 }
1867206
207+static void clearTmpModule(void)
208+{
209+ memset(pattTmp, 0, sizeof (pattTmp));
210+ memset(instrTmp, 0, sizeof (instrTmp));
211+ memset(&songTmp, 0, sizeof (songTmp));
212+
213+ for (uint32_t i = 0; i < MAX_PATTERNS; i++)
214+ pattLensTmp[i] = 64;
215+}
216+
1868217 static int32_t SDLCALL loadMusicThread(void *ptr)
1869218 {
1870219 return doLoadMusic(true);
1871−
1872220 (void)ptr;
1873221 }
1874222
1875223 void loadMusic(UNICHAR *filenameU)
1876224 {
1877− if (musicIsLoading)
225+ if (musicIsLoading || filenameU == NULL)
1878226 return;
1879227
1880228 mouseAnimOn();
@@ -1882,19 +230,9 @@ void loadMusic(UNICHAR *filenameU) · 1 unmodified line
1882230 musicIsLoading = true;
1883231 moduleLoaded = false;
1884232 moduleFailedToLoad = false;
1885− loadedFormat = FORMAT_NONE;
1886233
1887− UNICHAR_STRCPY(editor.tmpFilenameU, filenameU);
1888−
1889− // clear deprecated pointers from possible last loading session (super important)
1890− memset(pattTmp, 0, sizeof (pattTmp));
1891− memset(instrTmp, 0, sizeof (instrTmp));
1892−
1893− // prevent stuck instrument names from previous module
1894− memset(&songTmp, 0, sizeof (songTmp));
1895−
1896− for (uint32_t i = 0; i < MAX_PATTERNS; i++)
1897− pattLensTmp[i] = 64;
234+ clearTmpModule(); // clear stuff from last loading session (very important)
235+ UNICHAR_STRCPY(editor.tmpFilenameU, filenameU);
1898236
1899237 thread = SDL_CreateThread(loadMusicThread, NULL, NULL);
1900238 if (thread == NULL)
@@ -1910,19 +248,10 @@ void loadMusic(UNICHAR *filenameU) · 9 unmodified lines
1910248
1911249 bool loadMusicUnthreaded(UNICHAR *filenameU, bool autoPlay)
1912250 {
1913− if (filenameU == NULL || editor.tmpFilenameU == NULL)
251+ if (filenameU == NULL)
1914252 return false;
1915253
1916− // clear deprecated pointers from possible last loading session (super important)
1917− memset(pattTmp, 0, sizeof (pattTmp));
1918− memset(instrTmp, 0, sizeof (instrTmp));
1919−
1920− // prevent stuck instrument names from previous module
1921− memset(&songTmp, 0, sizeof (songTmp));
1922−
1923− for (uint32_t i = 0; i < MAX_PATTERNS; i++)
1924− pattLensTmp[i] = 64;
1925−
254+ clearTmpModule(); // clear stuff from last loading session (very important)
1926255 UNICHAR_STRCPY(editor.tmpFilenameU, filenameU);
1927256
1928257 editor.loadMusicEvent = EVENT_NONE;
@@ -1940,6 +269,36 @@ bool loadMusicUnthreaded(UNICHAR *filenameU, bool autoPlay) · 11 unmodified lines
1940269 return false;
1941270 }
1942271
272+bool allocateTmpPatt(int32_t nr, uint16_t rows)
273+{
274+ pattTmp[nr] = (tonTyp *)calloc((MAX_PATT_LEN * TRACK_WIDTH) + 16, 1);
275+ if (pattTmp[nr] == NULL)
276+ return false;
277+
278+ pattLensTmp[nr] = rows;
279+ return true;
280+}
281+
282+bool allocateTmpInstr(int16_t nr)
283+{
284+ if (instrTmp[nr] != NULL)
285+ return false; // already allocated
286+
287+ instrTyp *p = (instrTyp *)calloc(1, sizeof (instrTyp));
288+ if (p == NULL)
289+ return false;
290+
291+ sampleTyp *s = p->samp;
292+ for (int32_t i = 0; i < MAX_SMP_PER_INST; i++, s++)
293+ {
294+ s->pan = 128;
295+ s->vol = 64;
296+ }
297+
298+ instrTmp[nr] = p;
299+ return true;
300+}
301+
1943302 static void freeTmpModule(void) // called on module load error
1944303 {
1945304 // free all patterns
@@ -1970,404 +329,7 @@ static void freeTmpModule(void) // called on module load error · 24 unmodified lines
1970329 }
1971330 }
1972331
1973−static bool loadInstrHeader(FILE *f, uint16_t i, bool externalThreadFlag)
1974−{
1975− int8_t k;
1976− uint8_t j;
1977− uint32_t readSize;
1978− instrHeaderTyp ih;
1979− instrTyp *ins;
1980− sampleHeaderTyp *src;
1981− sampleTyp *s;
1982− int16_t (*showMsg)(int16_t, const char *, const char *);
1983−
1984− showMsg = externalThreadFlag ? okBoxThreadSafe : okBox;
1985−
1986− memset(extraSampleLengths, 0, sizeof (extraSampleLengths));
1987− memset(&ih, 0, sizeof (ih));
1988− fread(&ih.instrSize, 4, 1, f);
1989−
1990− readSize = ih.instrSize;
1991−
1992− // yes, some XMs can have a header size of 0, and it usually means 263 bytes (INSTR_HEADER_SIZE)
1993− if (readSize == 0 || readSize > INSTR_HEADER_SIZE)
1994− readSize = INSTR_HEADER_SIZE;
1995−
1996− if (readSize < 4)
1997− {
1998− showMsg(0, "System message", "Error loading XM: This file is corrupt (or not supported)!");
1999− return false;
2000− }
2001−
2002− // load instrument data into temp buffer
2003− fread(ih.name, readSize-4, 1, f); // -4 = skip ih.instrSize
2004−
2005− // FT2 bugfix: skip instrument header data if instrSize is above INSTR_HEADER_SIZE
2006− if (ih.instrSize > INSTR_HEADER_SIZE)
2007− fseek(f, ih.instrSize-INSTR_HEADER_SIZE, SEEK_CUR);
2008−
2009− if (ih.antSamp < 0 || ih.antSamp > 32)
2010− {
2011− showMsg(0, "System message", "Error loading XM: This file is corrupt (or not supported)!");
2012− return false;
2013− }
2014−
2015− if (i <= MAX_INST) // copy over instrument names
2016− {
2017− // trim off spaces at end of name
2018− for (k = 21; k >= 0; k--)
2019− {
2020− if (ih.name[k] == ' ' || ih.name[k] == 0x1A)
2021− ih.name[k] = '\0';
2022− else
2023− break;
2024− }
2025−
2026− memcpy(songTmp.instrName[i], ih.name, 22);
2027− songTmp.instrName[i][22] = '\0';
2028− }
2029−
2030− if (ih.antSamp > 0)
2031− {
2032− if (!allocateTmpInstr(i))
2033− {
2034− showMsg(0, "System message", "Not enough memory!");
2035− return false;
2036− }
2037−
2038− // copy instrument header elements to our instrument struct
2039−
2040− ins = instrTmp[i];
2041− memcpy(ins->ta, ih.ta, 96);
2042− memcpy(ins->envVP, ih.envVP, 12*2*sizeof(int16_t));
2043− memcpy(ins->envPP, ih.envPP, 12*2*sizeof(int16_t));
2044− ins->envVPAnt = ih.envVPAnt;
2045− ins->envPPAnt = ih.envPPAnt;
2046− ins->envVSust = ih.envVSust;
2047− ins->envVRepS = ih.envVRepS;
2048− ins->envVRepE = ih.envVRepE;
2049− ins->envPSust = ih.envPSust;
2050− ins->envPRepS = ih.envPRepS;
2051− ins->envPRepE = ih.envPRepE;
2052− ins->envVTyp = ih.envVTyp;
2053− ins->envPTyp = ih.envPTyp;
2054− ins->vibTyp = ih.vibTyp;
2055− ins->vibSweep = ih.vibSweep;
2056− ins->vibDepth = ih.vibDepth;
2057− ins->vibRate = ih.vibRate;
2058− ins->fadeOut = ih.fadeOut;
2059− ins->midiOn = (ih.midiOn == 1) ? true : false;
2060− ins->midiChannel = ih.midiChannel;
2061− ins->midiProgram = ih.midiProgram;
2062− ins->midiBend = ih.midiBend;
2063− ins->mute = (ih.mute == 1) ? true : false;
2064− ins->antSamp = ih.antSamp; // used in loadInstrSample()
2065−
2066− // sanitize stuff for broken/unsupported instruments
2067− ins->midiProgram = CLAMP(ins->midiProgram, 0, 127);
2068− ins->midiBend = CLAMP(ins->midiBend, 0, 36);
2069−
2070− if (ins->midiChannel > 15) ins->midiChannel = 15;
2071− if (ins->vibDepth > 0x0F) ins->vibDepth = 0x0F;
2072− if (ins->vibRate > 0x3F) ins->vibRate = 0x3F;
2073− if (ins->vibTyp > 3) ins->vibTyp = 0;
2074−
2075− for (j = 0; j < 96; j++)
2076− {
2077− if (ins->ta[j] >= MAX_SMP_PER_INST)
2078− ins->ta[j] = MAX_SMP_PER_INST-1;
2079− }
2080−
2081− if (ins->envVPAnt > 12) ins->envVPAnt = 12;
2082− if (ins->envVRepS > 11) ins->envVRepS = 11;
2083− if (ins->envVRepE > 11) ins->envVRepE = 11;
2084− if (ins->envVSust > 11) ins->envVSust = 11;
2085− if (ins->envPPAnt > 12) ins->envPPAnt = 12;
2086− if (ins->envPRepS > 11) ins->envPRepS = 11;
2087− if (ins->envPRepE > 11) ins->envPRepE = 11;
2088− if (ins->envPSust > 11) ins->envPSust = 11;
2089−
2090− for (j = 0; j < 12; j++)
2091− {
2092− if ((uint16_t)ins->envVP[j][0] > 32767) ins->envVP[j][0] = 32767;
2093− if ((uint16_t)ins->envPP[j][0] > 32767) ins->envPP[j][0] = 32767;
2094− if ((uint16_t)ins->envVP[j][1] > 64) ins->envVP[j][1] = 64;
2095− if ((uint16_t)ins->envPP[j][1] > 63) ins->envPP[j][1] = 63;
2096− }
2097−
2098− int32_t sampleHeadersToRead = ih.antSamp;
2099− if (sampleHeadersToRead > MAX_SMP_PER_INST)
2100− sampleHeadersToRead = MAX_SMP_PER_INST;
2101−
2102− if (fread(ih.samp, sampleHeadersToRead * sizeof (sampleHeaderTyp), 1, f) != 1)
2103− {
2104− showMsg(0, "System message", "General I/O error during loading!");
2105− return false;
2106− }
2107−
2108− // if instrument contains more than 16 sample headers (unsupported), skip them
2109− if (ih.antSamp > MAX_SMP_PER_INST) // can only be 0..32 at this point
2110− {
2111− const int32_t samplesToSkip = ih.antSamp-MAX_SMP_PER_INST;
2112− for (j = 0; j < samplesToSkip; j++)
2113− {
2114− fread(&extraSampleLengths[j], 4, 1, f); // used for skipping data in loadInstrSample()
2115− fseek(f, sizeof (sampleHeaderTyp)-4, SEEK_CUR);
2116− }
2117− }
2118−
2119− for (j = 0; j < sampleHeadersToRead; j++)
2120− {
2121− s = &instrTmp[i]->samp[j];
2122− src = &ih.samp[j];
2123−
2124− // copy sample header elements to our sample struct
2125−
2126− s->len = src->len;
2127− s->repS = src->repS;
2128− s->repL = src->repL;
2129− s->vol = src->vol;
2130− s->fine = src->fine;
2131− s->typ = src->typ;
2132− s->pan = src->pan;
2133− s->relTon = src->relTon;
2134− memcpy(s->name, src->name, 22);
2135− s->name[22] = '\0';
2136−
2137− // dst->pek is set up later
2138−
2139− // trim off spaces at end of name
2140− for (k = 21; k >= 0; k--)
2141− {
2142− if (s->name[k] == ' ' || s->name[k] == 0x1A)
2143− s->name[k] = '\0';
2144− else
2145− break;
2146− }
2147−
2148− // sanitize stuff broken/unsupported samples
2149− if (s->vol > 64)
2150− s->vol = 64;
2151−
2152− s->relTon = CLAMP(s->relTon, -48, 71);
2153− }
2154− }
2155−
2156− return true;
2157−}
2158−
2159−void checkSampleRepeat(sampleTyp *s)
2160−{
2161− if (s->repS < 0) s->repS = 0;
2162− if (s->repL < 0) s->repL = 0;
2163− if (s->repS > s->len) s->repS = s->len;
2164− if (s->repS+s->repL > s->len) s->repL = s->len - s->repS;
2165− if (s->repL == 0) s->typ &= ~3; // non-FT2 fix: force loop off if looplen is 0
2166−}
2167−
2168−static bool loadInstrSample(FILE *f, uint16_t i, bool externalThreadFlag)
2169−{
2170− int16_t (*showMsg)(int16_t, const char *, const char *);
2171−
2172− showMsg = externalThreadFlag ? okBoxThreadSafe : okBox;
2173−
2174− if (instrTmp[i] == NULL)
2175− return true; // empty instrument, let's just pretend it got loaded successfully
2176−
2177− uint16_t k = instrTmp[i]->antSamp;
2178− if (k > MAX_SMP_PER_INST)
2179− k = MAX_SMP_PER_INST;
2180−
2181− sampleTyp *s = instrTmp[i]->samp;
2182−
2183− if (i > MAX_INST) // insNum > 128, just skip sample data
2184− {
2185− for (uint16_t j = 0; j < k; j++, s++)
2186− {
2187− if (s->len > 0)
2188− fseek(f, s->len, SEEK_CUR);
2189− }
2190− }
2191− else
2192− {
2193− for (uint16_t j = 0; j < k; j++, s++)
2194− {
2195− // if a sample has both forward loop and pingpong loop set, make it pingpong loop only (FT2 mixer behavior)
2196− if ((s->typ & 3) == 3)
2197− s->typ &= 0xFE;
2198−
2199− int32_t l = s->len;
2200− if (l <= 0)
2201− {
2202− s->pek = NULL;
2203− s->len = 0;
2204− s->repL = 0;
2205− s->repS = 0;
2206−
2207− if (s->typ & 32)
2208− s->typ &= ~32; // remove stereo flag
2209− }
2210− else
2211− {
2212− int32_t bytesToSkip = 0;
2213− if (l > MAX_SAMPLE_LEN)
2214− {
2215− bytesToSkip = l - MAX_SAMPLE_LEN;
2216− l = MAX_SAMPLE_LEN;
2217− }
2218−
2219− s->pek = NULL;
2220− s->origPek = (int8_t *)malloc(l + LOOP_FIX_LEN);
2221− if (s->origPek == NULL)
2222− {
2223− showMsg(0, "System message", "Not enough memory!");
2224− return false;
2225− }
2226−
2227− s->pek = s->origPek + SMP_DAT_OFFSET;
2228−
2229− const int32_t bytesRead = (int32_t)fread(s->pek, 1, l, f);
2230− if (bytesRead < l)
2231− {
2232− const int32_t bytesToClear = l - bytesRead;
2233− memset(&s->pek[bytesRead], 0, bytesToClear);
2234− }
2235−
2236− if (bytesToSkip > 0)
2237− fseek(f, bytesToSkip, SEEK_CUR);
2238−
2239− delta2Samp(s->pek, l, s->typ);
2240−
2241− if (s->typ & 32) // stereo sample - already downmixed to mono in delta2samp()
2242− {
2243− s->typ &= ~32; // remove stereo flag
2244−
2245− s->len >>= 1;
2246− s->repL >>= 1;
2247− s->repS >>= 1;
2248−
2249− int8_t *newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN);
2250− if (newPtr != NULL)
2251− {
2252− s->origPek = newPtr;
2253− s->pek = s->origPek + SMP_DAT_OFFSET;
2254− }
2255− }
2256− }
2257−
2258− // NON-FT2 FIX: Align to 2-byte if 16-bit sample
2259− if (s->typ & 16)
2260− {
2261− s->repL &= 0xFFFFFFFE;
2262− s->repS &= 0xFFFFFFFE;
2263− s->len &= 0xFFFFFFFE;
2264− }
2265−
2266− checkSampleRepeat(s);
2267− fixSample(s);
2268− }
2269− }
2270−
2271− if (instrTmp[i]->antSamp > MAX_SMP_PER_INST)
2272− {
2273− const int32_t samplesToSkip = instrTmp[i]->antSamp-MAX_SMP_PER_INST;
2274− for (i = 0; i < samplesToSkip; i++)
2275− {
2276− if (extraSampleLengths[i] > 0)
2277− fseek(f, extraSampleLengths[i], SEEK_CUR);
2278− }
2279− }
2280−
2281− return true;
2282−}
2283−
2284−void unpackPatt(uint8_t *dst, uint8_t *src, uint16_t len, int32_t antChn)
2285−{
2286− int32_t j;
2287−
2288− if (dst == NULL)
2289− return;
2290−
2291− const int32_t srcEnd = len * (sizeof (tonTyp) * antChn);
2292− int32_t srcIdx = 0;
2293−
2294− int32_t numChannels = antChn;
2295− if (numChannels > MAX_VOICES)
2296− numChannels = MAX_VOICES;
2297−
2298− const int32_t pitch = sizeof (tonTyp) * (MAX_VOICES - antChn);
2299− for (int32_t i = 0; i < len; i++)
2300− {
2301− for (j = 0; j < numChannels; j++)
2302− {
2303− if (srcIdx >= srcEnd)
2304− return; // error!
2305−
2306− const uint8_t note = *src++;
2307− if (note & 0x80)
2308− {
2309− *dst++ = (note & 0x01) ? *src++ : 0;
2310− *dst++ = (note & 0x02) ? *src++ : 0;
2311− *dst++ = (note & 0x04) ? *src++ : 0;
2312− *dst++ = (note & 0x08) ? *src++ : 0;
2313− *dst++ = (note & 0x10) ? *src++ : 0;
2314− }
2315− else
2316− {
2317− *dst++ = note;
2318− *dst++ = *src++;
2319− *dst++ = *src++;
2320− *dst++ = *src++;
2321− *dst++ = *src++;
2322− }
2323−
2324− // if note is overflowing (>97), remove it
2325− if (*(dst-5) > 97)
2326− *(dst-5) = 0;
2327−
2328− // non-FT2 security fix: if effect is above 35 (Z), clear effect and parameter
2329− if (*(dst-2) > 35)
2330− {
2331− *(dst-2) = 0;
2332− *(dst-1) = 0;
2333− }
2334−
2335− srcIdx += sizeof (tonTyp);
2336− }
2337−
2338− // if more than 32 channels, skip rest of the channels for this row
2339− for (; j < antChn; j++)
2340− {
2341− if (srcIdx >= srcEnd)
2342− return; // error!
2343−
2344− const uint8_t note = *src++;
2345− if (note & 0x80)
2346− {
2347− if (note & 0x01) src++;
2348− if (note & 0x02) src++;
2349− if (note & 0x04) src++;
2350− if (note & 0x08) src++;
2351− if (note & 0x10) src++;
2352− }
2353− else
2354− {
2355− src++;
2356− src++;
2357− src++;
2358− src++;
2359− }
2360−
2361− srcIdx += sizeof (tonTyp);
2362− }
2363−
2364− // if song has <32 channels, align pointer to next row (skip unused channels)
2365− if (antChn < MAX_VOICES)
2366− dst += pitch;
2367− }
2368−}
2369−
2370−static bool tmpPatternEmpty(uint16_t nr)
332+bool tmpPatternEmpty(uint16_t nr)
2371333 {
2372334 if (pattTmp[nr] == NULL)
2373335 return true;
@@ -2396,97 +358,6 @@ void clearUnusedChannels(tonTyp *p, int16_t pattLen, int32_t antChn) · 22 unmodified lines
2396358 memset(ptr, 0, width);
2397359 }
2398360
2399−static bool loadPatterns(FILE *f, uint16_t antPtn, bool externalThreadFlag)
2400−{
2401− uint8_t tmpLen;
2402− patternHeaderTyp ph;
2403− int16_t (*showMsg)(int16_t, const char *, const char *);
2404−
2405− showMsg = externalThreadFlag ? okBoxThreadSafe : okBox;
2406−
2407− bool pattLenWarn = false;
2408− for (uint16_t i = 0; i < antPtn; i++)
2409− {
2410− if (fread(&ph.patternHeaderSize, 4, 1, f) != 1)
2411− goto pattCorrupt;
2412−
2413− if (fread(&ph.typ, 1, 1, f) != 1)
2414− goto pattCorrupt;
2415−
2416− ph.pattLen = 0;
2417− if (songTmp.ver == 0x0102)
2418− {
2419− if (fread(&tmpLen, 1, 1, f) != 1)
2420− goto pattCorrupt;
2421−
2422− if (fread(&ph.dataLen, 2, 1, f) != 1)
2423− goto pattCorrupt;
2424−
2425− ph.pattLen = tmpLen + 1; // +1 in v1.02
2426−
2427− if (ph.patternHeaderSize > 8)
2428− fseek(f, ph.patternHeaderSize - 8, SEEK_CUR);
2429− }
2430− else
2431− {
2432− if (fread(&ph.pattLen, 2, 1, f) != 1)
2433− goto pattCorrupt;
2434−
2435− if (fread(&ph.dataLen, 2, 1, f) != 1)
2436− goto pattCorrupt;
2437−
2438− if (ph.patternHeaderSize > 9)
2439− fseek(f, ph.patternHeaderSize - 9, SEEK_CUR);
2440− }
2441−
2442− if (feof(f))
2443− goto pattCorrupt;
2444−
2445− pattLensTmp[i] = ph.pattLen;
2446− if (pattLensTmp[i] > MAX_PATT_LEN)
2447− {
2448− pattLensTmp[i] = MAX_PATT_LEN;
2449− pattLenWarn = true;
2450− }
2451−
2452− if (ph.dataLen > 0)
2453− {
2454− pattTmp[i] = (tonTyp *)calloc((MAX_PATT_LEN * TRACK_WIDTH) + 16, 1);
2455− if (pattTmp[i] == NULL)
2456− {
2457− showMsg(0, "System message", "Not enough memory!");
2458− return false;
2459− }
2460−
2461− if (fread(packedPattData, 1, ph.dataLen, f) != ph.dataLen)
2462− goto pattCorrupt;
2463−
2464− unpackPatt((uint8_t *)pattTmp[i], packedPattData, pattLensTmp[i], songTmp.antChn);
2465− clearUnusedChannels(pattTmp[i], pattLensTmp[i], songTmp.antChn);
2466− }
2467−
2468− if (tmpPatternEmpty(i))
2469− {
2470− if (pattTmp[i] != NULL)
2471− {
2472− free(pattTmp[i]);
2473− pattTmp[i] = NULL;
2474− }
2475−
2476− pattLensTmp[i] = 64;
2477− }
2478− }
2479−
2480− if (pattLenWarn)
2481− showMsg(0, "System message", "This module contains pattern(s) with a length above 256! They will be truncated.");
2482−
2483− return true;
2484−
2485−pattCorrupt:
2486− showMsg(0, "System message", "Error loading XM: This file is corrupt!");
2487− return false;
2488−}
2489−
2490361 // called from input/video thread after the module was done loading
2491362 static void setupLoadedModule(void)
2492363 {
@@ -2513,16 +384,28 @@ static void setupLoadedModule(void) · 20 unmodified lines
2513384 pattLens[i] = pattLensTmp[i];
2514385 }
2515386
387+ // copy over song struct
388+ memcpy(&song, &songTmp, sizeof (songTyp));
389+ fixSongName();
390+
2516391 // copy over new instruments (includes sample pointers)
2517392 for (int16_t i = 1; i <= MAX_INST; i++)
2518393 {
2519394 instr[i] = instrTmp[i];
2520− fixSampleName(i);
2521− }
395+ fixInstrAndSampleNames(i);
2522396
2523− // copy over song struct
2524− memcpy(&song, &songTmp, sizeof (songTyp));
2525− fixSongName();
397+ if (instr[i] != NULL)
398+ {
399+ for (int32_t j = 0; j < MAX_SMP_PER_INST; j++)
400+ {
401+ sampleTyp *s = &instr[i]->samp[j];
402+
403+ checkSampleRepeat(s);
404+ if (s->pek != NULL)
405+ fixSample(s); // prepare sample for branchless linear interpolation
406+ }
407+ }
408+ }
2526409
2527410 // we are the owners of the allocated memory ptrs set by the loader thread now
2528411
@@ -2555,10 +438,7 @@ static void setupLoadedModule(void) · 26 unmodified lines
2555438 editor.timer = song.timer;
2556439 editor.globalVol = song.globVol;
2557440
2558− if (loadedFormat == FORMAT_XM)
2559− setFrqTab(linearFreqTable);
2560− else
2561− setFrqTab(false);
441+ setFrqTab(tmpLinearPeriodsFlag);
2562442
2563443 unlockMixerCallback();
2564444
@@ -2639,14 +519,9 @@ bool handleModuleLoadFromArg(int argc, char **argv) · 74 unmodified lines
2639519 UNICHAR_CHDIR(editor.binaryPathU);
2640520
2641521 const int32_t filesize = getFileSize(filenameU);
2642− if (filesize == -1 || filesize >= 512L*1024*1024) // >=2GB or >=512MB
522+ if (filesize == -1 || filesize >= 512L*1024*1024) // 1) >=2GB 2) >=512MB
2643523 {
2644524 okBox(0, "System message", "Error: The module is too big to be loaded!");
2645− /* This is not really true, but let's add this check to prevent accidentally
2646− ** passing really big files to the program. And how often do you really
2647− ** see a >=512MB .XM/.S3M module?
2648− */
2649−
2650525 free(filenameU);
2651526 UNICHAR_CHDIR(tmpPathU); // set old path back
2652527 return false;
@@ -2659,6 +534,64 @@ bool handleModuleLoadFromArg(int argc, char **argv) · 6 unmodified lines
2659534 return result;
2660535 }
2661536
537+static bool fileIsModule(UNICHAR *pathU)
538+{
539+ FILE *f = UNICHAR_FOPEN(pathU, "rb");
540+ if (f == NULL)
541+ return false;
542+
543+ int8_t modFormat = detectModule(f);
544+ fclose(f);
545+
546+ /* If the module was not identified (possibly STK type),
547+ ** check the file extension and handle it as a module only
548+ ** if it starts with "mod."/"stk." or ends with ".mod"/".stk" (case insensitive).
549+ */
550+ if (modFormat == FORMAT_POSSIBLY_STK)
551+ {
552+ char *path = unicharToCp437(pathU, false);
553+ if (path == NULL)
554+ return false;
555+
556+ int32_t pathLen = (int32_t)strlen(path);
557+
558+ // get filename from path
559+ int32_t i = pathLen;
560+ while (i--)
561+ {
562+ if (path[i] == DIR_DELIMITER)
563+ break;
564+ }
565+
566+ char *filename = path;
567+ if (i > 0)
568+ filename += i + 1;
569+
570+ int32_t filenameLen = (int32_t)strlen(filename);
571+ // --------------------------
572+
573+ if (filenameLen > 5)
574+ {
575+ if (!_strnicmp("mod.", filename, 4) || !_strnicmp("stk.", filename, 4))
576+ {
577+ free(path);
578+ return true;
579+ }
580+
581+ if (!_strnicmp(".mod", &filename[filenameLen-4], 4) || !_strnicmp(".stk", &filename[filenameLen-4], 4))
582+ {
583+ free(path);
584+ return true;
585+ }
586+ }
587+
588+ free(path);
589+ return false;
590+ }
591+
592+ return (modFormat != FORMAT_UNKNOWN);
593+}
594+
2662595 void loadDroppedFile(char *fullPathUTF8, bool songModifiedCheck)
2663596 {
2664597 if (ui.sysReqShown || fullPathUTF8 == NULL)
@@ -2701,15 +634,11 @@ void loadDroppedFile(char *fullPathUTF8, bool songModifiedCheck) · 36 unmodified lines
2701634
2702635 // pass UTF8 to these tests so that we can test file ending in ASCII/ANSI
2703636
2704− if (fileIsInstrument(fullPathUTF8))
637+ if (fileIsInstr(fullPathU))
2705638 {
2706639 loadInstr(fullPathU);
2707640 }
2708− else if (fileIsSample(fullPathUTF8))
2709− {
2710− loadSample(fullPathU, editor.curSmp, false);
2711− }
2712− else
641+ else if (fileIsModule(fullPathU))
2713642 {
2714643 SDL_RestoreWindow(video.window);
2715644
@@ -2729,6 +658,10 @@ void loadDroppedFile(char *fullPathUTF8, bool songModifiedCheck) · 13 unmodified lines
2729658 editor.loadMusicEvent = EVENT_LOADMUSIC_DRAGNDROP;
2730659 loadMusic(fullPathU);
2731660 }
661+ else
662+ {
663+ loadSample(fullPathU, editor.curSmp, false);
664+ }
2732665
2733666 free(fullPathU);
2734667 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t