summaryrefslogtreecommitdiff
path: root/apps/codecs/dumb/src/it/itread.c
diff options
context:
space:
mode:
authorMartin Arver <martin.arver@gmail.com>2006-12-11 21:01:14 +0000
committerMartin Arver <martin.arver@gmail.com>2006-12-11 21:01:14 +0000
commit7d820556e95ce8837eaa5baf2f6b5215a4b129ce (patch)
tree686899f7652fcd3c43c321ca53d99bbdfca42847 /apps/codecs/dumb/src/it/itread.c
parent440513ab6a51c5cc311ce8671180970279e4eaf9 (diff)
downloadrockbox-7d820556e95ce8837eaa5baf2f6b5215a4b129ce.zip
rockbox-7d820556e95ce8837eaa5baf2f6b5215a4b129ce.tar.gz
rockbox-7d820556e95ce8837eaa5baf2f6b5215a4b129ce.tar.bz2
rockbox-7d820556e95ce8837eaa5baf2f6b5215a4b129ce.tar.xz
Remove the files
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11719 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/dumb/src/it/itread.c')
-rw-r--r--apps/codecs/dumb/src/it/itread.c1181
1 files changed, 0 insertions, 1181 deletions
diff --git a/apps/codecs/dumb/src/it/itread.c b/apps/codecs/dumb/src/it/itread.c
deleted file mode 100644
index 0e78943..0000000
--- a/apps/codecs/dumb/src/it/itread.c
+++ /dev/null
@@ -1,1181 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itread.c - Code to read an Impulse Tracker / / \ \
- * module from an open file. | < / \_
- * | \/ /\ /
- * Based on the loader from an IT player by Bob. \_ / > /
- * Adapted for DUMB by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <string.h>//might not be necessary later; required for memset
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-#define INVESTIGATE_OLD_INSTRUMENTS
-
-
-
-static int it_seek(DUMBFILE *f, long offset)
-{
- long pos = dumbfile_pos(f);
-
- if (pos > offset)
- return -1;
-
- if (pos < offset)
- if (dumbfile_skip(f, offset - pos))
- return -1;
-
- return 0;
-}
-
-
-
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long dword;
-
-
-
-static unsigned char *sourcebuf = NULL;
-static unsigned char *sourcepos = NULL;
-static unsigned char *sourceend;
-static int rembits = 0;
-
-
-
-static int readblock(DUMBFILE *f)
-{
- long size;
- int c;
-
- size = dumbfile_igetw(f);
- if (size < 0)
- return size;
-
- sourcebuf = malloc(size);
- if (!sourcebuf)
- return -1;
-
- c = dumbfile_getnc((char *)sourcebuf, size, f);
- if (c < size) {
- free(sourcebuf);
- sourcebuf = NULL;
- return -1;
- }
-
- sourcepos = sourcebuf;
- sourceend = sourcebuf + size;
- rembits = 8;
- return 0;
-}
-
-
-
-static void freeblock(void)
-{
- free(sourcebuf);
- sourcebuf = NULL;
-}
-
-
-
-static int readbits(int bitwidth)
-{
- int val = 0;
- int b = 0;
-
- if (sourcepos >= sourceend) return val;
-
- while (bitwidth > rembits) {
- val |= *sourcepos++ << b;
- if (sourcepos >= sourceend) return val;
- b += rembits;
- bitwidth -= rembits;
- rembits = 8;
- }
-
- val |= (*sourcepos & ((1 << bitwidth) - 1)) << b;
- *sourcepos >>= bitwidth;
- rembits -= bitwidth;
-
- return val;
-}
-
-
-
-/** WARNING - do we even need to pass `right`? */
-/** WARNING - why bother memsetting at all? The whole array is written... */
-// if we do memset, dumb_silence() would be neater...
-static int decompress8(DUMBFILE *f, sample_t *left, sample_t *right, int len, int cmwt)
-{
- int blocklen, blockpos;
- byte bitwidth;
- word val;
- char d1, d2;
-
- memset(left, 0, len * sizeof(*left));
- if (right) {
- memset(right, 0, len * sizeof(*right));
- len <<= 1;
- }
-
- while (len > 0) {
- //Read a block of compressed data:
- if (readblock(f))
- return -1;
- //Set up a few variables
- blocklen = (len < 0x8000) ? len : 0x8000; //Max block length is 0x8000 bytes
- blockpos = 0;
- bitwidth = 9;
- d1 = d2 = 0;
- //Start the decompression:
- while (blockpos < blocklen) {
- //Read a value:
- val = (word)readbits(bitwidth);
- //Check for bit width change:
-
- if (bitwidth < 7) { //Method 1:
- if (val == (1 << (bitwidth - 1))) {
- val = (word)readbits(3) + 1;
- bitwidth = (val < bitwidth) ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth < 9) { //Method 2
- byte border = (0xFF >> (9 - bitwidth)) - 4;
-
- if (val > border && val <= (border + 8)) {
- val -= border;
- bitwidth = (val < bitwidth) ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth == 9) { //Method 3
- if (val & 0x100) {
- bitwidth = (val + 1) & 0xFF;
- continue;
- }
- }
- else { //Illegal width, abort ?
- freeblock();
- return -1;
- }
-
- //Expand the value to signed byte:
- {
- char v; //The sample value:
- if (bitwidth < 8) {
- byte shift = 8 - bitwidth;
- v = (val << shift);
- v >>= shift;
- }
- else
- v = (char)val;
-
- //And integrate the sample value
- //(It always has to end with integration doesn't it ? ;-)
- d1 += v;
- d2 += d1;
- }
-
- //Store !
- /* Version 2.15 was an unofficial version with hacked compression
- * code. Yay, better compression :D
- */
- if (right && (len & 1))
- *right++ = (int)(signed char)(cmwt == 0x215 ? d2 : d1) << 16;
- else
- *left++ = (int)(signed char)(cmwt == 0x215 ? d2 : d1) << 16;
- len--;
- blockpos++;
- }
- freeblock();
- }
- return 0;
-}
-
-
-
-static int decompress16(DUMBFILE *f, sample_t *left, sample_t *right, int len, int cmwt)
-{
- int blocklen, blockpos;
- byte bitwidth;
- long val;
- short d1, d2;
-
- memset(left, 0, len * sizeof(*left));
- if (right) {
- memset(right, 0, len * sizeof(*right));
- len <<= 1;
- }
-
- while (len > 0) {
- //Read a block of compressed data:
- if (readblock(f))
- return -1;
- //Set up a few variables
- blocklen = (len < 0x4000) ? len : 0x4000; // Max block length is 0x4000 bytes
- blockpos = 0;
- bitwidth = 17;
- d1 = d2 = 0;
- //Start the decompression:
- while (blockpos < blocklen) {
- val = readbits(bitwidth);
- //Check for bit width change:
-
- if (bitwidth < 7) { //Method 1:
- if (val == (1 << (bitwidth - 1))) {
- val = readbits(4) + 1;
- bitwidth = (val < bitwidth) ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth < 17) { //Method 2
- word border = (0xFFFF >> (17 - bitwidth)) - 8;
-
- if (val > border && val <= (border + 16)) {
- val -= border;
- bitwidth = val < bitwidth ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth == 17) { //Method 3
- if (val & 0x10000) {
- bitwidth = (val + 1) & 0xFF;
- continue;
- }
- }
- else { //Illegal width, abort ?
- freeblock();
- return -1;
- }
-
- //Expand the value to signed byte:
- {
- short v; //The sample value:
- if (bitwidth < 16) {
- byte shift = 16 - bitwidth;
- v = (short)(val << shift);
- v >>= shift;
- }
- else
- v = (short)val;
-
- //And integrate the sample value
- //(It always has to end with integration doesn't it ? ;-)
- d1 += v;
- d2 += d1;
- }
-
- //Store !
- /* Version 2.15 was an unofficial version with hacked compression
- * code. Yay, better compression :D
- */
- if (right && (len & 1))
- *right++ = (int)(signed short)(cmwt == 0x215 ? d2 : d1) << 8;
- else
- *left++ = (int)(signed short)(cmwt == 0x215 ? d2 : d1) << 8;
- len--;
- blockpos++;
- }
- freeblock();
- }
- return 0;
-}
-
-
-
-static int it_read_envelope(IT_ENVELOPE *envelope, DUMBFILE *f)
-{
- int n;
-
- envelope->flags = dumbfile_getc(f);
- envelope->n_nodes = dumbfile_getc(f);
- envelope->loop_start = dumbfile_getc(f);
- envelope->loop_end = dumbfile_getc(f);
- envelope->sus_loop_start = dumbfile_getc(f);
- envelope->sus_loop_end = dumbfile_getc(f);
- for (n = 0; n < envelope->n_nodes; n++) {
- envelope->node_y[n] = dumbfile_getc(f);
- envelope->node_t[n] = dumbfile_igetw(f);
- }
- dumbfile_skip(f, 75 - envelope->n_nodes * 3 + 1);
-
- return dumbfile_error(f);
-}
-
-
-
-static int it_read_old_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f)
-{
- int n;
-
- if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
- return -1;
-
- /* Skip DOS Filename. */
- dumbfile_skip(f, 13);
-
- instrument->volume_envelope.flags = dumbfile_getc(f);
- instrument->volume_envelope.loop_start = dumbfile_getc(f);
- instrument->volume_envelope.loop_end = dumbfile_getc(f);
- instrument->volume_envelope.sus_loop_start = dumbfile_getc(f);
- instrument->volume_envelope.sus_loop_end = dumbfile_getc(f);
-
- /* Skip two unused bytes. */
- dumbfile_skip(f, 2);
-
- /* In the old instrument format, fadeout ranges from 0 to 64, and is
- * subtracted at intervals from a value starting at 512. In the new
- * format, all these values are doubled. Therefore we double when loading
- * from the old instrument format - that way we don't have to think about
- * it later.
- */
- instrument->fadeout = dumbfile_igetw(f) << 1;
- instrument->new_note_action = dumbfile_getc(f);
- instrument->dup_check_type = dumbfile_getc(f);
- instrument->dup_check_action = DCA_NOTE_CUT; // This might be wrong!
- /** WARNING - what is the duplicate check action for old-style instruments? */
-
- /* Skip Tracker Version and Number of Samples. These are only used in
- * separate instrument files. Also skip unused bytes and Instrument Name.
- */
- dumbfile_skip(f, 36);
-
- instrument->pp_separation = 0;
- instrument->pp_centre = 60;
- instrument->global_volume = 128;
- /** WARNING - should global_volume be 64 or something? */
- instrument->default_pan = 32;
- /** WARNING - should default_pan be 128, meaning don`t use? */
- instrument->random_volume = 0;
- instrument->random_pan = 0;
-
- for (n = 0; n < 120; n++) {
- instrument->map_note[n] = dumbfile_getc(f);
- instrument->map_sample[n] = dumbfile_getc(f);
- }
-
- /* Skip "Volume envelope (200 bytes)". */
- // - need to know better what this is for though.
- dumbfile_skip(f, 200);
-
-#if defined(INVESTIGATE_OLD_INSTRUMENTS) && 0
- fprintf(stderr, "Inst %02d Env:", n);
-#endif
-
- for (n = 0; n < 25; n++)
- {
- instrument->volume_envelope.node_t[n] = dumbfile_getc(f);
- instrument->volume_envelope.node_y[n] = dumbfile_getc(f);
-
-#if defined(INVESTIGATE_OLD_INSTRUMENTS) && 0
- fprintf(stderr, " %d,%d",
- instrument->volume_envelope.node_t[n],
- instrument->volume_envelope.node_y[n]);
-#endif
-
- // This loop is unfinished, as we can probably escape from it before
- // the end if we want to. Hence the otherwise useless dumbfile_skip()
- // call below.
- }
- dumbfile_skip(f, 50 - (n << 1));
- instrument->volume_envelope.n_nodes = n;
-
-#if defined(INVESTIGATE_OLD_INSTRUMENTS) && 0
- fprintf(stderr, "\n");
-#endif
-
- if (dumbfile_error(f))
- return -1;
-
- instrument->filter_cutoff = 127;
- instrument->filter_resonance = 0;
-
- instrument->pan_envelope.flags = 0;
- instrument->pitch_envelope.flags = 0;
-
- return 0;
-}
-
-
-
-static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f)
-{
- int n;
-
- if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
- return -1;
-
- /* Skip DOS Filename. */
- dumbfile_skip(f, 13);
-
- instrument->new_note_action = dumbfile_getc(f);
- instrument->dup_check_type = dumbfile_getc(f);
- instrument->dup_check_action = dumbfile_getc(f);
- instrument->fadeout = dumbfile_igetw(f);
- instrument->pp_separation = dumbfile_getc(f);
- instrument->pp_centre = dumbfile_getc(f);
- instrument->global_volume = dumbfile_getc(f);
- instrument->default_pan = dumbfile_getc(f);
- instrument->random_volume = dumbfile_getc(f);
- instrument->random_pan = dumbfile_getc(f);
-
- /* Skip Tracker Version and Number of Samples. These are only used in
- * separate instrument files. Also skip unused byte and Instrument Name.
- */
- dumbfile_skip(f, 30);
-
- instrument->filter_cutoff = dumbfile_getc(f);
- instrument->filter_resonance = dumbfile_getc(f);
-
- /* Skip MIDI Channel, Program and Bank. */
- dumbfile_skip(f, 4);
-
- for (n = 0; n < 120; n++) {
- instrument->map_note[n] = dumbfile_getc(f);
- instrument->map_sample[n] = dumbfile_getc(f);
- }
-
- if (dumbfile_error(f))
- return -1;
-
- if (it_read_envelope(&instrument->volume_envelope, f)) return -1;
- if (it_read_envelope(&instrument->pan_envelope, f)) return -1;
- if (it_read_envelope(&instrument->pitch_envelope, f)) return -1;
-
- return 0;
-}
-
-
-
-static int it_read_sample_header(IT_SAMPLE *sample, unsigned char *convert, long *offset, DUMBFILE *f)
-{
- if (dumbfile_mgetl(f) != IT_SAMPLE_SIGNATURE)
- return -1;
-
- /* Skip DOS Filename. */
- dumbfile_skip(f, 13);
-
- sample->global_volume = dumbfile_getc(f);
- sample->flags = dumbfile_getc(f);
- sample->default_volume = dumbfile_getc(f);
-
- /* Skip Sample Name. */
- dumbfile_skip(f, 26);
-
- *convert = dumbfile_getc(f);
- sample->default_pan = dumbfile_getc(f);
- sample->length = dumbfile_igetl(f);
- sample->loop_start = dumbfile_igetl(f);
- sample->loop_end = dumbfile_igetl(f);
- sample->C5_speed = dumbfile_igetl(f);
- sample->sus_loop_start = dumbfile_igetl(f);
- sample->sus_loop_end = dumbfile_igetl(f);
-
-#ifdef STEREO_SAMPLES_COUNT_AS_TWO
- if (sample->flags & IT_SAMPLE_STEREO) {
- sample->length >>= 1;
- sample->loop_start >>= 1;
- sample->loop_end >>= 1;
- sample->C5_speed >>= 1;
- sample->sus_loop_start >>= 1;
- sample->sus_loop_end >>= 1;
- }
-#endif
-
- if (sample->flags & IT_SAMPLE_EXISTS) {
- if (sample->length <= 0)
- sample->flags &= ~IT_SAMPLE_EXISTS;
- else {
- if ((unsigned int)sample->loop_end > (unsigned int)sample->length)
- sample->flags &= ~IT_SAMPLE_LOOP;
- else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end)
- sample->flags &= ~IT_SAMPLE_LOOP;
-
- if ((unsigned int)sample->sus_loop_end > (unsigned int)sample->length)
- sample->flags &= ~IT_SAMPLE_SUS_LOOP;
- else if ((unsigned int)sample->sus_loop_start >= (unsigned int)sample->sus_loop_end)
- sample->flags &= ~IT_SAMPLE_SUS_LOOP;
-
- /* We may be able to truncate the sample to save memory. */
- if (sample->flags & IT_SAMPLE_LOOP) {
- if ((sample->flags & IT_SAMPLE_SUS_LOOP) && sample->sus_loop_end >= sample->loop_end)
- sample->length = sample->sus_loop_end;
- else
- sample->length = sample->loop_end;
- }
- }
- }
-
- *offset = dumbfile_igetl(f);
-
- sample->vibrato_speed = dumbfile_getc(f);
- sample->vibrato_depth = dumbfile_getc(f);
- sample->vibrato_rate = dumbfile_getc(f);
- sample->vibrato_waveform = dumbfile_getc(f);
-
- return dumbfile_error(f);
-}
-
-
-
-static long it_read_sample_data(int cmwt, IT_SAMPLE *sample, unsigned char convert, DUMBFILE *f)
-{
- long n;
-
- sample->left = malloc(sample->length * sizeof(*sample->left));
- if (!sample->left)
- return -1;
-
- if (sample->flags & IT_SAMPLE_STEREO) {
- sample->right = malloc(sample->length * sizeof(*sample->right));
- if (!sample->right)
- return -1;
- }
-
- if (sample->flags & 8) {
- /* If the sample is packed, then we must unpack it. */
-
- /** WARNING - unresolved business here... test with ModPlug? */
-
- if (sample->flags & IT_SAMPLE_STEREO)
- return -1;
-
-/*
-//#ifndef STEREO_SAMPLES_COUNT_AS_TWO
- ASSERT(!(sample->flags & IT_SAMPLE_STEREO));
-//#endif
-*/
- if (sample->flags & IT_SAMPLE_16BIT)
- decompress16(f, sample->left, sample->right, sample->length, cmwt);
- else
- decompress8(f, sample->left, sample->right, sample->length, cmwt);
- } else if (sample->flags & IT_SAMPLE_STEREO) {
- if (sample->flags & IT_SAMPLE_16BIT) {
- if (convert & 2) {
- for (n = 0; n < sample->length; n++) {
- sample->left[n] = (int)(signed short)dumbfile_mgetw(f) << 8;
- sample->right[n] = (int)(signed short)dumbfile_mgetw(f) << 8;
- }
- } else {
- for (n = 0; n < sample->length; n++) {
- sample->left[n] = (int)(signed short)dumbfile_igetw(f) << 8;
- sample->right[n] = (int)(signed short)dumbfile_igetw(f) << 8;
- }
- }
- } else {
- for (n = 0; n < sample->length; n++) {
- sample->left[n] = (int)(signed char)dumbfile_getc(f) << 16;
- sample->right[n] = (int)(signed char)dumbfile_getc(f) << 16;
- }
- }
- } else if (sample->flags & IT_SAMPLE_16BIT) {
- if (convert & 2)
- for (n = 0; n < sample->length; n++)
- sample->left[n] = (int)(signed short)dumbfile_mgetw(f) << 8;
- else
- for (n = 0; n < sample->length; n++)
- sample->left[n] = (int)(signed short)dumbfile_igetw(f) << 8;
- } else
- for (n = 0; n < sample->length; n++)
- sample->left[n] = (int)(signed char)dumbfile_getc(f) << 16;
-
- if (dumbfile_error(f))
- return -1;
-
- if (!(convert & 1)) {
- /* Convert to signed. */
- for (n = 0; n < sample->length; n++)
- sample->left[n] ^= 0xFF800000;
-
- if (sample->right)
- for (n = 0; n < sample->length; n++)
- sample->right[n] ^= 0xFF800000;
- }
-
- /* NOT SUPPORTED:
- *
- * convert & 4 - Samples stored as delta values
- * convert & 16 - Samples stored as TX-Wave 12-bit values
- * convert & 32 - Left/Right/All Stereo prompt
- */
-
- return 0;
-}
-
-
-
-#define DETECT_DUPLICATE_CHANNELS
-#ifdef DETECT_DUPLICATE_CHANNELS
-#include <stdio.h>
-#endif
-static int it_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer)
-{
- unsigned char cmask[DUMB_IT_N_CHANNELS];
- unsigned char cnote[DUMB_IT_N_CHANNELS];
- unsigned char cinstrument[DUMB_IT_N_CHANNELS];
- unsigned char cvolpan[DUMB_IT_N_CHANNELS];
- unsigned char ceffect[DUMB_IT_N_CHANNELS];
- unsigned char ceffectvalue[DUMB_IT_N_CHANNELS];
-#ifdef DETECT_DUPLICATE_CHANNELS
- IT_ENTRY *dupentry[DUMB_IT_N_CHANNELS];
-#endif
-
- int n_entries = 0;
- int buflen;
- int bufpos = 0;
-
- IT_ENTRY *entry;
-
- unsigned char channel;
- unsigned char mask;
-
- memset(cmask, 0, sizeof(cmask));
- memset(cnote, 0, sizeof(cnote));
- memset(cinstrument, 0, sizeof(cinstrument));
- memset(cvolpan, 0, sizeof(cvolpan));
- memset(ceffect, 0, sizeof(ceffect));
- memset(ceffectvalue, 0, sizeof(ceffectvalue));
-#ifdef DETECT_DUPLICATE_CHANNELS
- {
- int i;
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) dupentry[i] = NULL;
- }
-#endif
-
- buflen = dumbfile_igetw(f);
- pattern->n_rows = dumbfile_igetw(f);
-
- /* Skip four unused bytes. */
- dumbfile_skip(f, 4);
-
- if (dumbfile_error(f))
- return -1;
-
- /* Read in the pattern data. */
- dumbfile_getnc((char *)buffer, buflen, f);
-
- if (dumbfile_error(f))
- return -1;
-
- /* Scan the pattern data, and work out how many entries we need room for. */
- while (bufpos < buflen) {
- unsigned char b = buffer[bufpos++];
-
- if (b == 0) {
- /* End of row */
- n_entries++;
- continue;
- }
-
- channel = (b - 1) & 63;
-
- if (b & 128)
- cmask[channel] = mask = buffer[bufpos++];
- else
- mask = cmask[channel];
-
- {
- static const unsigned char used[16] = {0, 1, 1, 2, 1, 2, 2, 3, 2, 3, 3, 4, 3, 4, 4, 5};
- n_entries += (mask != 0);
- bufpos += used[mask & 15];
- }
- }
-
- pattern->n_entries = n_entries;
-
- pattern->entry = malloc(n_entries * sizeof(*pattern->entry));
-
- if (!pattern->entry)
- return -1;
-
- bufpos = 0;
- memset(cmask, 0, sizeof(cmask));
-
- entry = pattern->entry;
-
- while (bufpos < buflen) {
- unsigned char b = buffer[bufpos++];
-
- if (b == 0) {
- /* End of row */
- IT_SET_END_ROW(entry);
- entry++;
-#ifdef DETECT_DUPLICATE_CHANNELS
- {
- int i;
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) dupentry[i] = NULL;
- }
-#endif
- continue;
- }
-
- channel = (b - 1) & 63;
-
- if (b & 128)
- cmask[channel] = mask = buffer[bufpos++];
- else
- mask = cmask[channel];
-
- if (mask) {
- entry->mask = (mask & 15) | (mask >> 4);
- entry->channel = channel;
-
- if (mask & IT_ENTRY_NOTE)
- cnote[channel] = entry->note = buffer[bufpos++];
- else if (mask & (IT_ENTRY_NOTE << 4))
- entry->note = cnote[channel];
-
- if (mask & IT_ENTRY_INSTRUMENT)
- cinstrument[channel] = entry->instrument = buffer[bufpos++];
- else if (mask & (IT_ENTRY_INSTRUMENT << 4))
- entry->instrument = cinstrument[channel];
-
- if (mask & IT_ENTRY_VOLPAN)
- cvolpan[channel] = entry->volpan = buffer[bufpos++];
- else if (mask & (IT_ENTRY_VOLPAN << 4))
- entry->volpan = cvolpan[channel];
-
- if (mask & IT_ENTRY_EFFECT) {
- ceffect[channel] = entry->effect = buffer[bufpos++];
- ceffectvalue[channel] = entry->effectvalue = buffer[bufpos++];
- } else {
- entry->effect = ceffect[channel];
- entry->effectvalue = ceffectvalue[channel];
- }
-
-#if defined( DETECT_DUPLICATE_CHANNELS) && 0
- if (dupentry[channel]) {
- FILE *f = fopen("dupentry.txt", "a");
- if (!f) abort();
- fprintf(f, "Two events on channel %d:", channel);
- fprintf(f, " Event #1:");
- if (dupentry[channel]->mask & IT_ENTRY_NOTE ) fprintf(f, " %03d", dupentry[channel]->note ); else fprintf(f, " ...");
- if (dupentry[channel]->mask & IT_ENTRY_INSTRUMENT) fprintf(f, " %03d", dupentry[channel]->instrument); else fprintf(f, " ...");
- if (dupentry[channel]->mask & IT_ENTRY_VOLPAN ) fprintf(f, " %03d", dupentry[channel]->volpan ); else fprintf(f, " ...");
- if (dupentry[channel]->mask & IT_ENTRY_EFFECT) fprintf(f, " %c%02X\n", 'A' - 1 + dupentry[channel]->effect, dupentry[channel]->effectvalue); else fprintf(f, " ...\n");
- fprintf(f, " Event #2:");
- if (entry->mask & IT_ENTRY_NOTE ) fprintf(f, " %03d", entry->note ); else fprintf(f, " ...");
- if (entry->mask & IT_ENTRY_INSTRUMENT) fprintf(f, " %03d", entry->instrument); else fprintf(f, " ...");
- if (entry->mask & IT_ENTRY_VOLPAN ) fprintf(f, " %03d", entry->volpan ); else fprintf(f, " ...");
- if (entry->mask & IT_ENTRY_EFFECT) fprintf(f, " %c%02X\n", 'A' - 1 + entry->effect, entry->effectvalue); else fprintf(f, " ...\n");
- fclose(f);
- }
- dupentry[channel] = entry;
-#endif
-
- entry++;
- }
- }
-
- ASSERT(entry == pattern->entry + n_entries);
-
- return 0;
-}
-
-
-
-/* Currently we assume the sample data are stored after the sample headers in
- * module files. This assumption may be unjustified; let me know if you have
- * trouble.
- */
-
-#define IT_COMPONENT_INSTRUMENT 1
-#define IT_COMPONENT_PATTERN 2
-#define IT_COMPONENT_SAMPLE 3
-
-typedef struct IT_COMPONENT
-{
- unsigned char type;
- unsigned char n;
- long offset;
- short sampfirst; /* component[sampfirst] = first sample data after this */
- short sampnext; /* sampnext is used to create linked lists of sample data */
-}
-IT_COMPONENT;
-
-
-
-static int it_component_compare(const void *e1, const void *e2)
-{
- return ((const IT_COMPONENT *)e1)->offset -
- ((const IT_COMPONENT *)e2)->offset;
-}
-
-
-
-static sigdata_t *it_load_sigdata(DUMBFILE *f)
-{
- DUMB_IT_SIGDATA *sigdata;
-
- int cwt, cmwt;
- int special;
-
- IT_COMPONENT *component;
- int n_components = 0;
-
- unsigned char sample_convert[256];
-
- int n;
-
- unsigned char *buffer;
-
- if (dumbfile_mgetl(f) != IT_SIGNATURE)
- return NULL;
-
- sigdata = malloc(sizeof(*sigdata));
-
- if (!sigdata)
- return NULL;
-
- sigdata->order = NULL;
- sigdata->instrument = NULL;
- sigdata->sample = NULL;
- sigdata->pattern = NULL;
- sigdata->midi = NULL;
- sigdata->checkpoint = NULL;
-
- /* Skip song name and pattern row highlight info. */
- dumbfile_skip(f, 28);
-
- sigdata->n_orders = dumbfile_igetw(f);
- sigdata->n_instruments = dumbfile_igetw(f);
- sigdata->n_samples = dumbfile_igetw(f);
- sigdata->n_patterns = dumbfile_igetw(f);
-
- cwt = dumbfile_igetw(f);
- cmwt = dumbfile_igetw(f);
-
- sigdata->flags = dumbfile_igetw(f);
- special = dumbfile_igetw(f);
-
- sigdata->global_volume = dumbfile_getc(f);
- sigdata->mixing_volume = dumbfile_getc(f);
- sigdata->speed = dumbfile_getc(f);
- if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo?
- sigdata->tempo = dumbfile_getc(f);
- sigdata->pan_separation = dumbfile_getc(f); /** WARNING: use this */
-
- /* Skip Pitch Wheel Depth, Message Length, Message Offset and Reserved. */
- dumbfile_skip(f, 11);
-
- dumbfile_getnc((char *)sigdata->channel_pan, DUMB_IT_N_CHANNELS, f);
- dumbfile_getnc((char *)sigdata->channel_volume, DUMB_IT_N_CHANNELS, f);
-
- if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_instruments > 256 || sigdata->n_samples > 256 || sigdata->n_patterns > 256) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- sigdata->order = malloc(sigdata->n_orders);
- if (!sigdata->order) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (sigdata->n_instruments) {
- sigdata->instrument = malloc(sigdata->n_instruments * sizeof(*sigdata->instrument));
- if (!sigdata->instrument) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- }
-
- if (sigdata->n_samples) {
- sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
- if (!sigdata->sample) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (n = 0; n < sigdata->n_samples; n++)
- sigdata->sample[n].right = sigdata->sample[n].left = NULL;
- }
-
- if (sigdata->n_patterns) {
- sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
- if (!sigdata->pattern) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (n = 0; n < sigdata->n_patterns; n++)
- sigdata->pattern[n].entry = NULL;
- }
-
- dumbfile_getnc((char *)sigdata->order, sigdata->n_orders, f);
- sigdata->restart_position = 0;
-
- component = malloc(768 * sizeof(*component));
- if (!component) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- for (n = 0; n < sigdata->n_instruments; n++) {
- component[n_components].type = IT_COMPONENT_INSTRUMENT;
- component[n_components].n = n;
- component[n_components].offset = dumbfile_igetl(f);
- component[n_components].sampfirst = -1;
- n_components++;
- }
-
- for (n = 0; n < sigdata->n_samples; n++) {
- component[n_components].type = IT_COMPONENT_SAMPLE;
- component[n_components].n = n;
- component[n_components].offset = dumbfile_igetl(f);
- component[n_components].sampfirst = -1;
- n_components++;
- }
-
- for (n = 0; n < sigdata->n_patterns; n++) {
- long offset = dumbfile_igetl(f);
- if (offset) {
- component[n_components].type = IT_COMPONENT_PATTERN;
- component[n_components].n = n;
- component[n_components].offset = offset;
- component[n_components].sampfirst = -1;
- n_components++;
- } else {
- /* Empty 64-row pattern */
- sigdata->pattern[n].n_rows = 64;
- sigdata->pattern[n].n_entries = 0;
- }
- }
-
- if (dumbfile_error(f)) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (!(sigdata->flags & 128) != !(special & 8)) {
-#if 0
- fprintf(stderr, "Flags Bit 7 (\"Request embedded MIDI configuration\"): %s\n", sigdata->flags & 128 ? "=SET=" : "clear");
- fprintf(stderr, "Special Bit 3 (\"MIDI configuration embedded\") : %s\n", special & 8 ? "=SET=" : "clear");
- fprintf(stderr, "entheh would like to investigate this IT file.\n");
- fprintf(stderr, "Please contact him! entheh@users.sf.net\n");
-#endif
- }
-
- if (special & 8) {
- /* MIDI configuration is embedded. */
- unsigned char mididata[32];
- int i;
- sigdata->midi = malloc(sizeof(*sigdata->midi));
- if (!sigdata->midi) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- // Should we be happy with this outcome in some situations?
- }
- // What are we skipping?
- i = dumbfile_igetw(f);
- if (dumbfile_error(f) || dumbfile_skip(f, 8*i)) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- /* Read embedded MIDI configuration */
- // What are the first 9 commands for?
- if (dumbfile_skip(f, 32*9)) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (i = 0; i < 16; i++) {
- unsigned char len = 0;
- int j, leftdigit = -1;
- if (dumbfile_getnc((char *)mididata, 32, f) < 32) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- sigdata->midi->SFmacroz[i] = 0;
- for (j = 0; j < 32; j++) {
- if (leftdigit >= 0) {
- if (mididata[j] == 0) {
- sigdata->midi->SFmacro[i][len++] = leftdigit;
- break;
- } else if (mididata[j] == ' ')
- sigdata->midi->SFmacro[i][len++] = leftdigit;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- sigdata->midi->SFmacro[i][len++] = (leftdigit << 4) | (mididata[j] - '0');
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- sigdata->midi->SFmacro[i][len++] = (leftdigit << 4) | (mididata[j] - 'A' + 0xA);
- leftdigit = -1;
- } else if (mididata[j] == 0)
- break;
- else if (mididata[j] == 'z')
- sigdata->midi->SFmacroz[i] |= 1 << len++;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- leftdigit = mididata[j] - '0';
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- leftdigit = mididata[j] - 'A' + 0xA;
- }
- sigdata->midi->SFmacrolen[i] = len;
- }
- for (i = 0; i < 128; i++) {
- unsigned char len = 0;
- int j, leftdigit = -1;
- dumbfile_getnc((char *)mididata, 32, f);
- for (j = 0; j < 32; j++) {
- if (leftdigit >= 0) {
- if (mididata[j] == 0) {
- sigdata->midi->Zmacro[i][len++] = leftdigit;
- break;
- } else if (mididata[j] == ' ')
- sigdata->midi->Zmacro[i][len++] = leftdigit;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- sigdata->midi->Zmacro[i][len++] = (leftdigit << 4) | (mididata[j] - '0');
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- sigdata->midi->Zmacro[i][len++] = (leftdigit << 4) | (mididata[j] - 'A' + 0xA);
- leftdigit = -1;
- } else if (mididata[j] == 0)
- break;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- leftdigit = mididata[j] - '0';
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- leftdigit = mididata[j] - 'A' + 0xA;
- }
- sigdata->midi->Zmacrolen[i] = len;
- }
- }
-
- sigdata->flags &= IT_REAL_FLAGS;
-
- qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare);
-
- buffer = malloc(65536);
- if (!buffer) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- for (n = 0; n < n_components; n++) {
- long offset;
- int m;
-
- if (it_seek(f, component[n].offset)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- switch (component[n].type) {
-
- case IT_COMPONENT_INSTRUMENT:
- if (cmwt < 0x200)
- m = it_read_old_instrument(&sigdata->instrument[component[n].n], f);
- else
- m = it_read_instrument(&sigdata->instrument[component[n].n], f);
-
- if (m) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- break;
-
- case IT_COMPONENT_PATTERN:
- if (it_read_pattern(&sigdata->pattern[component[n].n], f, buffer)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- break;
-
- case IT_COMPONENT_SAMPLE:
- if (it_read_sample_header(&sigdata->sample[component[n].n], &sample_convert[component[n].n], &offset, f)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (sigdata->sample[component[n].n].flags & IT_SAMPLE_EXISTS) {
- short *sample;
-
- for (m = n + 1; m < n_components; m++)
- if (component[m].offset > offset)
- break;
- m--;
-
- sample = &component[m].sampfirst;
-
- while (*sample >= 0 && component[*sample].offset <= offset)
- sample = &component[*sample].sampnext;
-
- component[n].sampnext = *sample;
- *sample = n;
-
- component[n].offset = offset;
- }
- }
-
- m = component[n].sampfirst;
-
- while (m >= 0) {
- if (it_seek(f, component[m].offset)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (it_read_sample_data(cmwt, &sigdata->sample[component[m].n], sample_convert[component[m].n], f)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- m = component[m].sampnext;
- }
- }
-
- free(buffer);
- free(component);
-
- _dumb_it_fix_invalid_orders(sigdata);
-
- return sigdata;
-}
-
-
-
-DUH *dumb_read_it(DUMBFILE *f)
-{
- sigdata_t *sigdata;
- long length;
-
- DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
-
- sigdata = it_load_sigdata(f);
-
- if (!sigdata)
- return NULL;
-
- length = _dumb_it_build_checkpoints(sigdata);
-
- return make_duh(length, 1, &descptr, &sigdata);
-}
-