From e763dfa3ddf5c499875a6e1e9ec91d7fc154c076 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Sun, 11 Apr 2010 15:01:21 +0200 Subject: moved DUMB to dynamic plugin --- plugins/dumb/dumb-kode54/src/tools/it/load_it.cpp | 824 ++++++++++++++++++++++ plugins/dumb/dumb-kode54/src/tools/it/modulus.h | 193 +++++ plugins/dumb/dumb-kode54/src/tools/it/typedef.hpp | 3 + 3 files changed, 1020 insertions(+) create mode 100644 plugins/dumb/dumb-kode54/src/tools/it/load_it.cpp create mode 100644 plugins/dumb/dumb-kode54/src/tools/it/modulus.h create mode 100644 plugins/dumb/dumb-kode54/src/tools/it/typedef.hpp (limited to 'plugins/dumb/dumb-kode54/src/tools/it') diff --git a/plugins/dumb/dumb-kode54/src/tools/it/load_it.cpp b/plugins/dumb/dumb-kode54/src/tools/it/load_it.cpp new file mode 100644 index 00000000..ed88e706 --- /dev/null +++ b/plugins/dumb/dumb-kode54/src/tools/it/load_it.cpp @@ -0,0 +1,824 @@ +#ifdef FORTIFY +#include "fortify.h" +#endif +#include +#ifdef MSS +#include "mss.h" +#endif + +#include + +#include "allegro.h" +#include "modulus.h" +#include "typedef.hpp" + +int detect_it(char *f) { + int sig; + PACKFILE *fn = pack_fopen(f, "rb"); + + if (fn == NULL) + return FALSE; + + sig = pack_mgetl(fn); + if (sig != AL_ID('I','M','P','M')) { + pack_fclose(fn); + return FALSE; + } + pack_fclose(fn); + + return TRUE; +} + +MODULUS *create_it() { + MODULUS *m = (MODULUS*)malloc(sizeof(MODULUS)); + if (!m) + return NULL; + memset(m, 0, sizeof(MODULUS)); + return m; +} + +void destroy_it(MODULUS *j) { + + if (song->Music == j) + stop_it(); + + //remove patterns: + for (int i=0; iNumPatterns; i++) { + free(j->Pattern[i].Note); + } + if (j->Pattern) + free(j->Pattern); + //remove instruments; + if (j->Instrument) + free(j->Instrument); + //remove samples; + for (int i=0; iNumSamples; i++) { + destroy_sample(j->Sample[i].Sample); + } + if (j->Sample) + free(j->Sample); + //remove orders: + if (j->Order) + free(j->Order); + //remove channels: + for (int i=0; i<64; i++) { + if (j->Channel[i].VChannel) { + MODULUS_VCHANNEL *vchn = song->Music->Channel[i].VChannel; + MODULUS_VCHANNEL *prev = NULL; + + if (!vchn) + continue; + + for (;;) { + deallocate_voice(vchn->voice); + + prev = vchn; + vchn = vchn->next; + free(prev); + + if (!vchn) + break; + } + } + } + free(j); +} + +//#define DEBUG_IT_SIZE + +int get_module_size(MODULUS *j) { + int a, b, c, d = 0, e; + a = sizeof(MODULUS) + j->NumOrders; + b = j->NumInstruments * sizeof(MODULUS_INSTRUMENT); + c = j->NumSamples * sizeof(MODULUS_SAMPLE); + + for (int i=0; iNumSamples; i++) + d += j->Sample[i].SampleLength * (j->Sample[i].Flag & 2 ? sizeof(short) : 1) * (j->Sample[i].Flag & 4 ? 2: 1); + + e = 4 + sizeof(MODULUS_PATTERN) * j->NumPatterns; + + for (int i=0; iNumPatterns; i++) + e += j->Pattern[i].NumNotes * sizeof(MODULUS_NOTE); + #ifdef DEBUG_IT_SIZE + printf("Base: %i, Instruments(%i): %i, Samples(%i): %i, Data: %i, Patterns(%i): %i\n", a, j->NumInstruments, b, j->NumSamples, c, d, j->NumPatterns, e); + #endif + + return a+b+c+d+e; +} + +#define MAX_IT_CHN 64 + +//#define DEBUG_HEADER +//#define DEBUG_INSTRUMENTS +//#define DEBUG_SAMPLES +//#define DEBUG_PATTERNS + +static dword *sourcebuf = NULL; +static dword *sourcepos = NULL; +static byte rembits = 0; + +int readblock(PACKFILE *f) { + long size; + int c = pack_igetw(f); + if (c == -1) + return 0; + size = c; + + sourcebuf = (dword*)malloc(size+4); + if (!sourcebuf) + return 0; + + c = pack_fread(sourcebuf, size, f); + if (c < 1) { + free(sourcebuf); + sourcebuf = NULL; + return 0; + } + sourcepos = sourcebuf; + rembits = 32; + return 1; +} + +void freeblock() { + if (sourcebuf) + free(sourcebuf); + sourcebuf = NULL; +} + +dword readbits(char b) { + dword val; + if (b <= rembits) { + val = *sourcepos & ((1 << b) - 1); + *sourcepos >>= b; + rembits -= b; + } + else { + dword nbits = b - rembits; + val = *sourcepos; + sourcepos++; + val |= ((*sourcepos & ((1 << nbits) - 1)) << rembits); + *sourcepos >>= nbits; + rembits = 32 - nbits; + } + return val; +} + +void decompress8(PACKFILE *f, void *data, int len, int tver) { + char *destbuf = (char*)data; + char *destpos = destbuf; + int blocklen, blockpos; + byte bitwidth; + word val; + char d1, d2; + + memset(destbuf, 0, len); + + while (len>0) { + //Read a block of compressed data: + if (!readblock(f)) + return; + //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 = readbits(bitwidth); + //Check for bit width change: + + if (bitwidth < 7) { //Method 1: + if (val == (1 << (bitwidth - 1))) { + val = 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; + } + + //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 ! + *destpos = ((tver == 0x215) ? d2 : d1); + destpos++; + blockpos++; + } + freeblock(); + len -= blocklen; + } + return; +} + +void decompress16(PACKFILE *f, void *data, int len, int tver) { + //make the output buffer: + short *destbuf = (short*)data; + short *destpos = destbuf; + int blocklen, blockpos; + byte bitwidth; + long val; + short d1, d2; + + memset(destbuf, 0, len); + + while (len>0) { + //Read a block of compressed data: + if (!readblock(f)) + return; + //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; + } + + //Expand the value to signed byte: + short v; //The sample value: + if (bitwidth < 16) { + byte shift = 16 - bitwidth; + v = (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 ! + *destpos = ((tver == 0x215) ? d2 : d1); + destpos++; + blockpos++; + } + freeblock(); + len -= blocklen; + } + return; +} + +MODULUS *load_it(char *file) { + PACKFILE *f; + MODULUS *j = create_it(); + int tver, tver2, flag, msglen, msgoffs; + int *insoffs = NULL, *samoffs = NULL, *patoffs = NULL; + + if (!j) + return NULL; + + if (!detect_it(file)) + return NULL; + + f = pack_fopen(file, "rb"); + + if (!f) { + #ifdef DEBUG_HEADER + printf("Error Opening!\n"); + #endif + return NULL; + } + + pack_fseek(f, 30); + pack_igetw(f); //I have no idea... + + j->NumOrders = pack_igetw(f); + j->NumInstruments = pack_igetw(f); + j->NumSamples = pack_igetw(f); + j->NumPatterns = pack_igetw(f); + + #ifdef DEBUG_HEADER + printf("Loading IT: %i Orders %i Instruments, %i Samples, %i Patterns\n", j->NumOrders, j->NumInstruments, j->NumSamples, j->NumPatterns); + #endif + + tver = pack_igetw(f); + j->Version = tver2 = pack_igetw(f); + + #ifdef DEBUG_HEADER + printf("Tracker ver: %X, %X\n", tver, tver2); + #endif + + j->Flags = pack_igetw(f); + flag = pack_igetw(f); + + j->GlobalVolume = pack_getc(f); + j->MixVolume = pack_getc(f); + j->Speed = pack_getc(f); + j->Tempo = pack_getc(f); + j->PanningSeperation = pack_getc(f); + + #ifdef DEBUG_HEADER + printf("Global Volume: %i, Mixing Volume: %i, Speed: %i, Tempo: %i, PanSep: %i\n", j->GlobalVolume, j->MixVolume, j->Speed, j->Tempo, j->PanningSeperation); + #endif + + pack_getc(f); //Damn....I need more info on this. + + msglen = pack_igetw(f); + msgoffs = pack_igetl(f); + + pack_fseek(f, 4); + + #ifdef DEBUG_HEADER + printf("Channel Pan:"); + #endif + + for (int i=0; iChannel[i].Pan = pack_getc(f); + #ifdef DEBUG_HEADER + printf(" %i", j->Channel[i].Pan); + #endif + } + #ifdef DEBUG_HEADER + printf("\nChannel Vol:"); + #endif + for (int i=0; iChannel[i].Volume = pack_getc(f); + #ifdef DEBUG_HEADER + printf(" %i", j->Channel[i].Volume); + #endif + } + #ifdef DEBUG_HEADER + printf("\n"); + #endif + + j->Order = (unsigned char *)malloc(j->NumOrders); + pack_fread(j->Order, j->NumOrders, f); + + if (j->NumInstruments) + insoffs = (int*)malloc(4 * j->NumInstruments); + if (j->NumSamples) + samoffs = (int*)malloc(4 * j->NumSamples); + if (j->NumPatterns) + patoffs = (int*)malloc(4 * j->NumPatterns); + + pack_fread(insoffs, 4 * j->NumInstruments, f); + pack_fread(samoffs, 4 * j->NumSamples, f); + pack_fread(patoffs, 4 * j->NumPatterns, f); + + if (flag&1) { //Song message attached + //Ignore. + } + if (flag & 4) { //skip something: + short u; + char dummy[8]; + u = pack_igetw(f); + for (int i=0; iNumInstruments) + j->Instrument = (MODULUS_INSTRUMENT*)malloc(sizeof(MODULUS_INSTRUMENT) * j->NumInstruments); + #ifdef DEBUG_INSTRUMENTS + if (!j->Instrument) + printf("No Mem for Instruments!\n"); + #endif + + + for (int i=0; iNumInstruments; i++) { + pack_fclose(f); + f = pack_fopen(file, "rb"); + #ifdef DEBUG_INSTRUMENTS + if (!f) + printf("Error Opening!\n"); + #endif + pack_fseek(f, insoffs[i] + 17); + + j->Instrument[i].NewNoteAction = pack_getc(f); + j->Instrument[i].DuplicateCheckType = pack_getc(f); + j->Instrument[i].DuplicateCheckAction = pack_getc(f); + j->Instrument[i].FadeOut = pack_igetw(f); + j->Instrument[i].PitchPanSeperation = pack_getc(f); + j->Instrument[i].PitchPanCenter = pack_getc(f); + j->Instrument[i].GlobalVolume = pack_getc(f); + j->Instrument[i].DefaultPan = pack_getc(f); + #ifdef DEBUG_INSTRUMENTS + printf("I%02i @ 0x%X, NNA %i, DCT %i, DCA %i, FO %i, PPS %i, PPC %i, GVol %i, DPan %i\n", i, insoffs[i], j->Instrument[i].NewNoteAction, j->Instrument[i].DuplicateCheckType, j->Instrument[i].DuplicateCheckAction, j->Instrument[i].FadeOut, j->Instrument[i].PitchPanSeperation, j->Instrument[i].PitchPanCenter, j->Instrument[i].GlobalVolume, j->Instrument[i].DefaultPan); + #endif + + pack_fseek(f, 38); + + for (int k=0; k<120; k++) { + j->Instrument[i].NoteNote[k] = pack_getc(f); + j->Instrument[i].NoteSample[k] = pack_getc(f) - 1; + } + + j->Instrument[i].VolumeEnvelope.Flag = pack_getc(f); + j->Instrument[i].VolumeEnvelope.NumNodes = pack_getc(f); + j->Instrument[i].VolumeEnvelope.LoopBegin = pack_getc(f); + j->Instrument[i].VolumeEnvelope.LoopEnd = pack_getc(f); + j->Instrument[i].VolumeEnvelope.SustainLoopBegin = pack_getc(f); + j->Instrument[i].VolumeEnvelope.SustainLoopEnd = pack_getc(f); + for (int k=0; kInstrument[i].VolumeEnvelope.NumNodes; k++) { + j->Instrument[i].VolumeEnvelope.NodeY[k] = pack_getc(f); + j->Instrument[i].VolumeEnvelope.NodeTick[k] = pack_igetw(f); + } + pack_fseek(f, 75 - j->Instrument[i].VolumeEnvelope.NumNodes * 3); + + j->Instrument[i].PanningEnvelope.Flag = pack_getc(f); + j->Instrument[i].PanningEnvelope.NumNodes = pack_getc(f); + j->Instrument[i].PanningEnvelope.LoopBegin = pack_getc(f); + j->Instrument[i].PanningEnvelope.LoopEnd = pack_getc(f); + j->Instrument[i].PanningEnvelope.SustainLoopBegin = pack_getc(f); + j->Instrument[i].PanningEnvelope.SustainLoopEnd = pack_getc(f); + for (int k=0; kInstrument[i].PanningEnvelope.NumNodes; k++) { + j->Instrument[i].PanningEnvelope.NodeY[k] = pack_getc(f); + j->Instrument[i].PanningEnvelope.NodeTick[k] = pack_igetw(f); + } + pack_fseek(f, 75 - j->Instrument[i].PanningEnvelope.NumNodes * 3); + + j->Instrument[i].PitchEnvelope.Flag = pack_getc(f); + j->Instrument[i].PitchEnvelope.NumNodes = pack_getc(f); + j->Instrument[i].PitchEnvelope.LoopBegin = pack_getc(f); + j->Instrument[i].PitchEnvelope.LoopEnd = pack_getc(f); + j->Instrument[i].PitchEnvelope.SustainLoopBegin = pack_getc(f); + j->Instrument[i].PitchEnvelope.SustainLoopEnd = pack_getc(f); + for (int k=0; kInstrument[i].PitchEnvelope.NumNodes; k++) { + j->Instrument[i].PitchEnvelope.NodeY[k] = pack_getc(f); + j->Instrument[i].PitchEnvelope.NodeTick[k] = pack_igetw(f); + } + } + + if (j->NumSamples) + j->Sample = (MODULUS_SAMPLE*)malloc(sizeof(MODULUS_SAMPLE) * j->NumSamples); + + #ifdef DEBUG_SAMPLES + if (!j->Sample) + printf("No Mem for Samples!\n"); + #endif + + for (int i=0; iNumSamples; i++) { + int sam_samptr, convert; + + pack_fclose(f); + f = pack_fopen(file, "rb"); + #ifdef DEBUG_SAMPLES + if (!f) + printf("Error opening!\n"); + #endif + + pack_fseek(f, samoffs[i] + 17); + + j->Sample[i].GlobalVolume = pack_getc(f); + j->Sample[i].Flag = pack_getc(f); + j->Sample[i].Volume = pack_getc(f); + + #ifdef DEBUG_SAMPLES + printf("S%02i @ 0x%X, Vol: %i/%i, Flag: %i", i, samoffs[i], j->Sample[i].GlobalVolume, j->Sample[i].Volume, j->Sample[i].Flag); + #endif + + pack_fseek(f, 26); + + convert = pack_getc(f); + pack_getc(f); //Panning ? + + j->Sample[i].SampleLength = pack_igetl(f); + j->Sample[i].LoopBegin = pack_igetl(f); + j->Sample[i].LoopEnd = pack_igetl(f); + j->Sample[i].C5Speed = pack_igetl(f); + j->Sample[i].SustainLoopBegin = pack_igetl(f); + j->Sample[i].SustainLoopEnd = pack_igetl(f); + + #ifdef DEBUG_SAMPLES + printf(", SLen: %i, LpB: %i, LpE: %i, C5S: %i\n", j->Sample[i].SampleLength, j->Sample[i].LoopBegin, j->Sample[i].LoopEnd, j->Sample[i].C5Speed); + #endif + + sam_samptr = pack_igetl(f); + + j->Sample[i].VibratoSpeed = pack_getc(f); + j->Sample[i].VibratoDepth = pack_getc(f); + j->Sample[i].VibratoRate = pack_getc(f); + j->Sample[i].VibratoWaveForm = pack_getc(f); + + #ifdef DEBUG_SAMPLES + printf("SusLpB: %i, SusLpE: %i, VibSp: %i, VibDep: %i, VibWav: %i, VibRat: %i\n", j->Sample[i].SustainLoopBegin, j->Sample[i].SustainLoopEnd, j->Sample[i].VibratoSpeed, j->Sample[i].VibratoDepth, j->Sample[i].VibratoWaveForm, j->Sample[i].VibratoRate); + #endif + + if (j->Sample[i].Flag & 1 == 0) + continue; + + pack_fclose(f); + f = pack_fopen(file, "rb"); + pack_fseek(f, sam_samptr); + + int len = j->Sample[i].SampleLength * (j->Sample[i].Flag & 2 ? sizeof(short) : 1) * (j->Sample[i].Flag & 4 ? 2: 1); + + #ifdef DEBUG_SAMPLES + printf("Len: %i, Size: %i KB\n", j->Sample[i].SampleLength, len/1024); + #endif + + SAMPLE *sam = create_sample(j->Sample[i].Flag & 2 ? 16 : 8, j->Sample[i].Flag & 4 ? TRUE : FALSE, j->Sample[i].C5Speed, j->Sample[i].SampleLength); + + if (j->Sample[i].Flag & 8) { // If the sample is packed, then we must unpack it + if (j->Sample[i].Flag & 2) + decompress16(f, sam->data, j->Sample[i].SampleLength, tver2); + else + decompress8(f, sam->data, j->Sample[i].SampleLength, tver2); + } else { + pack_fread(sam->data, len, f); + } + + if (j->Sample[i].Flag & SAMPLE_USELOOP) { + sam->loop_start = j->Sample[i].LoopBegin; + sam->loop_end = j->Sample[i].LoopEnd; + } + + j->Sample[i].Sample = sam; + + void *dat = sam->data; + + if (convert & 2) { //Change the byte order for 16-bit samples: + if (sam->bits == 16) { + for (int k=0; kbits == 8) { + for (int k=0; k>1); k++) { + ((short*)dat)[k] ^= 0x8000; + } + } + } + } + + if (j->NumPatterns) + j->Pattern = (MODULUS_PATTERN*)malloc(sizeof(MODULUS_PATTERN) * j->NumPatterns); + unsigned char *buf = (unsigned char*)alloca(65536); + unsigned char *cmask = (unsigned char*)alloca(64), + *cnote = (unsigned char*)alloca(64), + *cinstrument = (unsigned char*)alloca(64), + *cvol = (unsigned char*)alloca(64), + *ccom = (unsigned char*)alloca(64), + *ccomval = (unsigned char*)alloca(64); + + for (int i=0; iNumPatterns; i++) { + int numnotes = 0, len, pos = 0, mask = 0, chn = 0; + + memset(cmask, 0, 64); + memset(cnote, 0, 64); + memset(cinstrument, 0, 64); + memset(cvol, 0, 64); + memset(ccom, 0, 64); + memset(ccomval, 0, 64); + + pack_fclose(f); + f = pack_fopen(file, "rb"); + pack_fseek(f, patoffs[i]); + + len = pack_igetw(f); + j->Pattern[i].NumRows = pack_igetw(f); + + pack_fseek(f, 4); + pack_fread(buf, len, f); + + while (pos < len) { + int b = buf[pos]; + pos++; + if (!b) { //If end of row: + numnotes++; + continue; + } + chn = (b - 1) & 63; + + if (b & 128) { + mask = buf[pos]; + pos++; + cmask[chn] = mask; + } + else + mask = cmask[chn]; + + if (mask) + numnotes++; + if (mask & 1) + pos++; + if (mask & 2) + pos++; + if (mask & 4) + pos++; + if (mask & 8) + pos+=2; //Guessing here + } + j->Pattern[i].NumNotes = numnotes; + j->Pattern[i].Note = (MODULUS_NOTE*)malloc(sizeof(MODULUS_NOTE) * numnotes); + memset(j->Pattern[i].Note, 0, sizeof(MODULUS_NOTE) * numnotes); + + pos = 0; + memset(cmask, 0, 64); + mask = 0; + numnotes = 0; + while (pos < len) { + int b = buf[pos]; + #ifdef DEBUG_PATTERNS + printf("NumNote: %i ", numnotes); + #endif + + pos++; + if (!b) { //If end of row: + j->Pattern[i].Note[numnotes].Channel = -1; + numnotes++; + #ifdef DEBUG_PATTERNS + printf("Channel: -1\n"); + #endif + continue; + } + chn = (b - 1) & 63; + + if (b & 128) { + mask = buf[pos]; + pos++; + cmask[chn] = mask; + } + else + mask = cmask[chn]; + #ifdef DEBUG_PATTERNS + printf("Channel: %i Mask: %i ", chn, mask); + #endif + + if (mask) + j->Pattern[i].Note[numnotes].Channel = chn; + + if (mask & 1) { + j->Pattern[i].Note[numnotes].Note = buf[pos]; + j->Pattern[i].Note[numnotes].Mask |= 1; + cnote[chn] = buf[pos]; + #ifdef DEBUG_PATTERNS + printf("Note: %i ", buf[pos]); + #endif + pos++; + } + if (mask & 2) { + j->Pattern[i].Note[numnotes].Instrument = buf[pos]; + j->Pattern[i].Note[numnotes].Mask |= 2; + cinstrument[chn] = buf[pos]; + #ifdef DEBUG_PATTERNS + printf("Inst: %i ", buf[pos]); + #endif + pos++; + } + if (mask & 4) { + if (buf[pos] <= 64 || (buf[pos] >= 128 && buf[pos] <= 192)) + if (buf[pos] <= 64) { + j->Pattern[i].Note[numnotes].Volume = buf[pos]; + j->Pattern[i].Note[numnotes].Mask |= 4; + } + else { + j->Pattern[i].Note[numnotes].Panning = buf[pos] - 128; + j->Pattern[i].Note[numnotes].Mask |= 8; + } + #ifdef DEBUG_PATTERNS + printf("Vol: %i ", buf[pos]); + #endif + cvol[chn] = buf[pos]; + pos++; + } + if (mask & 8) { + j->Pattern[i].Note[numnotes].Command = buf[pos]; + j->Pattern[i].Note[numnotes].CommandValue = buf[pos+1]; + j->Pattern[i].Note[numnotes].Mask |= 16; + ccom[chn] = buf[pos]; + ccomval[chn] = buf[pos+1]; + #ifdef DEBUG_PATTERNS + printf("Com: %i CommArg: %i ", buf[pos], buf[pos+1]); + #endif + pos+=2; + } + if (mask & 16) { + j->Pattern[i].Note[numnotes].Note = cnote[chn]; + j->Pattern[i].Note[numnotes].Mask |= 1; + #ifdef DEBUG_PATTERNS + printf("LNote: %i ", cnote[chn]); + #endif + } + if (mask & 32) { + j->Pattern[i].Note[numnotes].Instrument = cinstrument[chn]; + j->Pattern[i].Note[numnotes].Mask |= 2; + #ifdef DEBUG_PATTERNS + printf("LInst: %i ", cinstrument[chn]); + #endif + } + if (mask & 64) { + if (cvol[chn] <= 64 || (cvol[chn] >= 128 && cvol[chn] <= 192)) + if (cvol[chn] <= 64) { + j->Pattern[i].Note[numnotes].Volume = cvol[chn]; + j->Pattern[i].Note[numnotes].Mask |= 4; + } + else { + j->Pattern[i].Note[numnotes].Panning = cvol[chn] - 128; + j->Pattern[i].Note[numnotes].Mask |= 8; + } + #ifdef DEBUG_PATTERNS + printf("LVol: %i ", cvol[chn]); + #endif + } + if (mask & 128) { + j->Pattern[i].Note[numnotes].Command = ccom[chn]; + j->Pattern[i].Note[numnotes].CommandValue = ccomval[chn]; + j->Pattern[i].Note[numnotes].Mask |= 16; + #ifdef DEBUG_PATTERNS + printf("LCom: %i LComArg: %i ", ccom[chn], ccomval[chn]); + #endif + } + #ifdef DEBUG_PATTERNS + printf("\n"); + #endif + if (mask) + numnotes++; + #ifdef DEBUG_PATTERNS + rest(1000); + #endif + } + } + if (insoffs) + free(insoffs); + if (samoffs) + free(samoffs); + if (patoffs) + free(patoffs); + + return j; +} diff --git a/plugins/dumb/dumb-kode54/src/tools/it/modulus.h b/plugins/dumb/dumb-kode54/src/tools/it/modulus.h new file mode 100644 index 00000000..b17d6ff6 --- /dev/null +++ b/plugins/dumb/dumb-kode54/src/tools/it/modulus.h @@ -0,0 +1,193 @@ + +#define MUSIC_IT AL_ID('I','M','P','M') + +typedef struct MODULUS_MUSIC_INFO { + char Name[29]; + int Type; +} MODULUS_MUSIC_INFO; + +#define ENVELOPE_ON 1 +#define ENVELOPE_LOOP_ON 2 +#define ENVELOPE_SUSTAINLOOP 4 + +typedef struct MODULUS_ENVELOPE { + unsigned char Flag, + NumNodes, + LoopBegin, LoopEnd, SustainLoopBegin, SustainLoopEnd; //in nodes. + char NodeY[25]; + short NodeTick[25]; +} MODULUS_ENVELOPE; + +typedef struct MODULUS_VENVELOPE { + char CurNode; + unsigned char CurTick; + char End; + //float CVolume; + MODULUS_ENVELOPE *Envelope; +} MODULUS_VENVELOPE; + +#define NNA_NOTECUT 1 +#define NNA_NOTECONTINUE 2 +#define NNA_NOTEOFF 3 +#define NNA_NOTEFADE 4 + +#define DCT_OFF 0 +#define DCT_NOTE 1 +#define DCT_SAMPLE 2 +#define DCT_INSTRUMENT 3 + +#define DCA_CUT 0 +#define DCA_NOTEOFF 1 +#define DCA_NOTEFADE 2 + +typedef struct MOULUS_INSTRUMENT { + unsigned char Flag; + char VolumeLoopNodeStart, VolumeLoopNodeEnd; + char SustainLoopNodeStart, SustainLoopNodeEnd; + char DuplicateCheckType; + char DuplicateCheckAction; + char NewNoteAction; + int FadeOut; + + unsigned char PitchPanSeperation, //0->64, Bit7: Don't use + PitchPanCenter; //Note, from C-0 to B-9 + unsigned char GlobalVolume, //0->128 + DefaultPan; //0->64, Bit7: Don't use + + + unsigned char NoteSample[120]; + unsigned char NoteNote[120]; + + MODULUS_ENVELOPE VolumeEnvelope, PanningEnvelope, PitchEnvelope; +} MODULUS_INSTRUMENT; + +#define SAMPLE_HASSAMPLE 1 +#define SAMPLE_16BIT 2 +#define SAMPLE_STEREO 4 +#define SAMPLE_USELOOP 16 +#define SAMPLE_USESUSTAINLOOP 32 +#define SAMPLE_PINGPONGLOOP 64 +#define SAMPLE_PINGPONGSUSTAINLOOP 128 + +#define VIBRATO_SINE 0 +#define VIBRATO_RAMPDOWN 1 +#define VIBRATO_SQUARE 2 +#define VIBRATO_RANDOM 3 + +typedef struct MODULUS_SAMPLE { + unsigned char GlobalVolume; //0->64 + unsigned char Flag; + unsigned char Volume; + int SampleLength; //in samples, not bytes ! + int LoopBegin, LoopEnd; //in samples + int SustainLoopBegin, SustainLoopEnd; + int C5Speed; //Number of bytes/sec for C-5 + + SAMPLE *Sample; + + char VibratoSpeed; //0->64 + char VibratoDepth; //0->64 + char VibratoWaveForm; + char VibratoRate; //0->64 +} MODULUS_SAMPLE; + +typedef struct MODULUS_NOTE { + char Mask; //If Bit0: Note, Bit1: Instrument, Bit2: Volume, Bit3: Panning, Bit4: Command + char Channel; //if -1, then end of row. + unsigned char Note; + char Instrument; + unsigned char Volume, Panning; + unsigned char Command, CommandValue; +} MODULUS_NOTE; + +typedef struct MODULUS_PATTERN { + int NumRows; + int NumNotes; + MODULUS_NOTE *Note; +} MODULUS_PATTERN; + +typedef struct MODULUS_VCHANNEL { + MODULUS_SAMPLE *Sample; //NULL is unused + char voice; + char ChannelVolume; + char NoteOn; + char NNA; + short FadeOutCount, FadeOut; + float MixVolume, MixPan; + MODULUS_VENVELOPE *VVolumeEnvelope, *VPanningEnvelope, *VPitchEnvelope; + MODULUS_VCHANNEL *next, *prev; +} MODULUS_VCHANNEL; + +typedef struct MODULUS_CHANNEL { + unsigned char Volume; //0->64 + unsigned char Pan; //0->32->64, 100 = surround, Bit7: Disable + char LastNote, LastInstrument, LastSample; + MODULUS_VCHANNEL *VChannel; +} MODULUS_CHANNEL; + +#define FLAG_STEREO 1 +#define FLAG_USEINSTRUMENTS 4 +#define FLAG_LINEARSLIDES 8 +#define FLAG_OLDEFFECT 16 + +typedef struct MODULUS { + MODULUS_INSTRUMENT *Instrument; + MODULUS_SAMPLE *Sample; + MODULUS_PATTERN *Pattern; + + int NumOrders; + int NumInstruments; + int NumSamples; + int NumPatterns; + int Flags; + short Version; + char GlobalVolume; + char MixVolume; + unsigned char Speed, Tempo; + char PanningSeperation; + + unsigned char *Order; + + MODULUS_CHANNEL Channel[64]; + +} MODULUS; + +#define COMMAND_SET_SONG_SPEED 1 +#define COMMAND_JUMP_TO_ORDER 2 +#define COMMAND_PATTERN_BREAK_TO_ROW 3 +#define COMMAND_SET_CHANNEL_VOLUME 13 +#define COMMAND_SET_SONG_TEMPO 20 +#define COMMAND_SET_GLOBAL_VOLUME 22 + +typedef struct MODULUS_PLAY { + MODULUS *Music; + int Loop, Tick; + int CurOrder, CurPattern, CurPos; + int Command, CommandVal0, CommandVal1, CommandVal2; + int pos; +} MODULUS_PLAY; +extern MODULUS_PLAY *song; + +extern int IT_Play_Method; + +MODULUS *load_it(char*); +int get_module_size(MODULUS *); + +int play_it(MODULUS *j, int loop); +void install_modulus(); +void set_mix_volume(int i); + +void stop_it(); +int is_music_done(); +void destroy_it(MODULUS *j); + +//Should be internal: +extern MODULUS_PLAY *song; +extern int note_freq[120]; + +extern void MOD_Interrupt(...); +extern int MOD_Poller(void*); + +#define IT_TIMER 0 +#define IT_POLL 1 + diff --git a/plugins/dumb/dumb-kode54/src/tools/it/typedef.hpp b/plugins/dumb/dumb-kode54/src/tools/it/typedef.hpp new file mode 100644 index 00000000..6d4eefee --- /dev/null +++ b/plugins/dumb/dumb-kode54/src/tools/it/typedef.hpp @@ -0,0 +1,3 @@ +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned int dword; -- cgit v1.2.3