static int it_asy_read_pattern( IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer ) { int pos; int channel; int row; IT_ENTRY *entry; pattern->n_rows = 64; if ( dumbfile_getnc( buffer, 64 * 8 * 4, f ) != 64 * 8 * 4 ) return -1; /* compute number of entries */ pattern->n_entries = 64; /* Account for the row end markers */ pos = 0; for ( row = 0; row < 64; ++row ) { for ( channel = 0; channel < 8; ++channel ) { if ( buffer[ pos + 0 ] | buffer[ pos + 1 ] | buffer[ pos + 2 ] | buffer[ pos + 3 ] ) ++pattern->n_entries; pos += 4; } } pattern->entry = malloc( pattern->n_entries * sizeof( *pattern->entry ) ); if ( !pattern->entry ) return -1; entry = pattern->entry; pos = 0; for ( row = 0; row < 64; ++row ) { for ( channel = 0; channel < 8; ++channel ) { if ( buffer[ pos + 0 ] | buffer[ pos + 1 ] | buffer[ pos + 2 ] | buffer[ pos + 3 ] ) { entry->channel = channel; entry->mask = 0; if ( buffer[ pos + 0 ] && buffer[ pos + 0 ] < 96 ) { entry->note = buffer[ pos + 0 ]; entry->mask |= IT_ENTRY_NOTE; } if ( buffer[ pos + 1 ] && buffer[ pos + 1 ] <= 64 ) { entry->instrument = buffer[ pos + 1 ]; entry->mask |= IT_ENTRY_INSTRUMENT; } _dumb_it_xm_convert_effect( buffer[ pos + 2 ], buffer[ pos + 3 ], entry, 1 ); if ( entry->mask ) ++entry; } pos += 4; } IT_SET_END_ROW( entry ); ++entry; } pattern->n_entries = (int)(entry - pattern->entry); return 0; }
static int it_xm_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, int n_channels, unsigned char *buffer, int version) { int size; int pos; int channel; int row; int effect, effectvalue; IT_ENTRY *entry; /* pattern header size */ if (dumbfile_igetl(f) != ( version == 0x0102 ? 0x08 : 0x09 ) ) { TRACE("XM error: unexpected pattern header size\n"); return -1; } /* pattern data packing type */ if (dumbfile_getc(f) != 0) { TRACE("XM error: unexpected pattern packing type\n"); return -1; } if ( version == 0x0102 ) pattern->n_rows = dumbfile_getc(f) + 1; else pattern->n_rows = dumbfile_igetw(f); /* 1..256 */ size = dumbfile_igetw(f); pattern->n_entries = 0; if (dumbfile_error(f)) return -1; if (size == 0) return 0; if (size > 1280 * n_channels) { TRACE("XM error: pattern data size > %d bytes\n", 1280 * n_channels); return -1; } if (dumbfile_getnc((char *)buffer, size, f) < size) return -1; /* compute number of entries */ pattern->n_entries = 0; pos = channel = row = 0; while (pos < size) { if (!(buffer[pos] & XM_ENTRY_PACKED) || (buffer[pos] & 31)) pattern->n_entries++; channel++; if (channel >= n_channels) { channel = 0; row++; pattern->n_entries++; } if (buffer[pos] & XM_ENTRY_PACKED) { static const char offset[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5 }; pos += 1 + offset[buffer[pos] & 31]; } else { pos += 5; } } if (row > pattern->n_rows) { TRACE("XM error: wrong number of rows in pattern data\n"); return -1; } /* Whoops, looks like some modules may be short, a few channels, maybe even rows... */ while (row < pattern->n_rows) { pattern->n_entries++; row++; } pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry)); if (!pattern->entry) return -1; /* read the entries */ entry = pattern->entry; pos = channel = row = 0; while (pos < size) { unsigned char mask; if (buffer[pos] & XM_ENTRY_PACKED) mask = buffer[pos++] & 31; else mask = 31; if (mask) { ASSERT(entry < pattern->entry + pattern->n_entries); entry->channel = channel; entry->mask = 0; if (mask & XM_ENTRY_NOTE) { int note = buffer[pos++]; /* 1-96 <=> C0-B7 */ entry->note = (note == XM_NOTE_OFF) ? (IT_NOTE_OFF) : (note-1); entry->mask |= IT_ENTRY_NOTE; } if (mask & XM_ENTRY_INSTRUMENT) { entry->instrument = buffer[pos++]; /* 1-128 */ entry->mask |= IT_ENTRY_INSTRUMENT; } if (mask & XM_ENTRY_VOLUME) it_xm_convert_volume(buffer[pos++], entry); effect = effectvalue = 0; if (mask & XM_ENTRY_EFFECT) effect = buffer[pos++]; if (mask & XM_ENTRY_EFFECTVALUE) effectvalue = buffer[pos++]; _dumb_it_xm_convert_effect(effect, effectvalue, entry, 0); entry++; } channel++; if (channel >= n_channels) { channel = 0; row++; IT_SET_END_ROW(entry); entry++; } } while (row < pattern->n_rows) { row++; IT_SET_END_ROW(entry); entry++; } return 0; }
static int it_riff_dsmf_process_pattern( IT_PATTERN * pattern, DUMBFILE * f, int len ) { int length, row; unsigned flags; long start, end; int p, q, r; IT_ENTRY * entry; length = dumbfile_igetw( f ); if ( length > len ) return -1; len = length - 2; pattern->n_rows = 64; pattern->n_entries = 64; row = 0; start = dumbfile_pos( f ); end = start + len; while ( (row < 64) && !dumbfile_error( f ) && (dumbfile_pos( f ) < end) ) { p = dumbfile_getc( f ); if ( ! p ) { ++ row; continue; } flags = p & 0xF0; if (flags) { ++ pattern->n_entries; if (flags & 0x80) dumbfile_skip( f, 1 ); if (flags & 0x40) dumbfile_skip( f, 1 ); if (flags & 0x20) dumbfile_skip( f, 1 ); if (flags & 0x10) dumbfile_skip( f, 2 ); } } if ( pattern->n_entries == 64 ) return 0; pattern->entry = malloc( pattern->n_entries * sizeof( * pattern->entry ) ); if ( ! pattern->entry ) return -1; entry = pattern->entry; row = 0; if ( dumbfile_seek( f, start, DFS_SEEK_SET ) ) return -1; while ( ( row < 64 ) && !dumbfile_error( f ) && ( dumbfile_pos( f ) < end ) ) { p = dumbfile_getc( f ); if ( ! p ) { IT_SET_END_ROW( entry ); ++ entry; ++ row; continue; } flags = p; entry->channel = flags & 0x0F; entry->mask = 0; if ( flags & 0xF0 ) { if ( flags & 0x80 ) { q = dumbfile_getc( f ); if ( q ) { entry->mask |= IT_ENTRY_NOTE; entry->note = q - 1; } } if ( flags & 0x40 ) { q = dumbfile_getc( f ); if ( q ) { entry->mask |= IT_ENTRY_INSTRUMENT; entry->instrument = q; } } if ( flags & 0x20 ) { entry->mask |= IT_ENTRY_VOLPAN; entry->volpan = dumbfile_getc( f ); } if ( flags & 0x10 ) { q = dumbfile_getc( f ); r = dumbfile_getc( f ); _dumb_it_xm_convert_effect( q, r, entry, 0 ); } if (entry->mask) entry++; } } while ( row < 64 ) { IT_SET_END_ROW( entry ); ++ entry; ++ row; } pattern->n_entries = entry - pattern->entry; if ( ! pattern->n_entries ) return -1; return 0; }
static int it_riff_dsmf_process_pattern( IT_PATTERN * pattern, const unsigned char * data, int len ) { int length, row, pos; unsigned flags; IT_ENTRY * entry; length = data[ 0 ] | ( data[ 1 ] << 8 ); if ( length > len ) return -1; data += 2; len = length - 2; pattern->n_rows = 64; pattern->n_entries = 64; row = 0; pos = 0; while ( (row < 64) && (pos < len) ) { if ( ! data[ pos ] ) { ++ row; ++ pos; continue; } flags = data[ pos++ ] & 0xF0; if (flags) { ++ pattern->n_entries; if (flags & 0x80) pos ++; if (flags & 0x40) pos ++; if (flags & 0x20) pos ++; if (flags & 0x10) pos += 2; } } if ( pattern->n_entries == 64 ) return 0; pattern->entry = malloc( pattern->n_entries * sizeof( * pattern->entry ) ); if ( ! pattern->entry ) return -1; entry = pattern->entry; row = 0; pos = 0; while ( ( row < 64 ) && ( pos < len ) ) { if ( ! data[ pos ] ) { IT_SET_END_ROW( entry ); ++ entry; ++ row; ++ pos; continue; } flags = data[ pos++ ]; entry->channel = flags & 0x0F; entry->mask = 0; if ( flags & 0xF0 ) { if ( flags & 0x80 ) { if ( data[ pos ] ) { entry->mask |= IT_ENTRY_NOTE; entry->note = data[ pos ] - 1; } ++ pos; } if ( flags & 0x40 ) { if ( data[ pos ] ) { entry->mask |= IT_ENTRY_INSTRUMENT; entry->instrument = data[ pos ]; } ++ pos; } if ( flags & 0x20 ) { entry->mask |= IT_ENTRY_VOLPAN; entry->volpan = data[ pos ]; ++ pos; } if ( flags & 0x10 ) { _dumb_it_xm_convert_effect( data[ pos ], data[ pos + 1 ], entry, 0 ); pos += 2; } if (entry->mask) entry++; } } while ( row < 64 ) { IT_SET_END_ROW( entry ); ++ entry; ++ row; } pattern->n_entries = (int)(entry - pattern->entry); if ( ! pattern->n_entries ) return -1; return 0; }