/*Copyright (C) 2014, Jeffrey Lim. All Rights Reserved. Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY ANDFITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE.*/ #include "it_struc.h" uint8_t SlideTable[9] = { 1, 4, 8, 16, 32, 64, 96, 128, 255 }; void InitVolumeEffectH(it_engine *ite, it_host *chn, uint8_t ah);void InitCommandD7(it_engine *ite, it_host *chn, it_slave *slave);void InitCommandG11(it_engine *ite, it_host *chn);void InitCommandX2(it_engine *ite, it_host *chn, uint8_t al);void CommandD2(it_engine *ite, it_host *chn, it_slave *slave, uint8_t al);void CommandEChain(it_engine *ite, it_host *chn, int16_t bx);void CommandFChain(it_engine *ite, it_host *chn, int16_t bx);void InitVibrato(it_engine *ite, it_host *chn);void CommandH5(it_engine *ite, it_host *chn, it_slave *slave, int8_t al);void InitTremelo(it_engine *ite, it_host *chn);void CommandR2(it_engine *ite, it_host *chn, it_slave *slave, int8_t al); /*// Not transcribing further unless there is a good reason to.int32_t GetC5Speed(uint8_t *ds, uint8_t *es, uint16_t bx){ if(*(uint8_t *)(ds + di + 0x0F) == 101) { // OK.. we have a MIDI sample // Check whether the midi sample points to a valid sample // And if so, use that sample's C5 speed. uint16_t si = *(uint8_t *)(ds + di + 0x03); // Not a note? uint32_t ebp = *(uint8_t *)(ds + di + 0x04); if(ebp != 0) // No sample? { si += si; ebp = *(uint16_t *)(es + 64710 + ebp + ebp); uint8_t al = *(uint8_t *)(es + ebp + si + 0x40) // AL = note uint8_t ah = *(uint8_t *)(es + ebp + si + 0x41) // AH = sample. if(ah != 0) // No sample? { si = ah*2; si = *(uint16_t *)(es + 64910 + si) // Sample offset if(*(uint8_t *)(es + si + 0x12) == 1) { bx = si; } } } } return *(uint8_t *)(es + bx + 0x3C); // EAX = C5Spd}*/ void InitVolumeEffect(it_engine *ite, it_host *chn) // Done A, B, H{ if((chn->Msk & 0x44) == 0) return; uint8_t al = chn->Vol; uint8_t ah = al; al &= 0x7F; if(al < 65) return; al -= 65; if((ah & 0x80) != 0) { al += 60; } uint8_t dl = 10; uint8_t tmpquo = al / dl; uint8_t tmprem = al % dl; al = tmpquo; // Effect number ah = tmprem; // Effect parameter chn->VCm = al; // Store effect number // Memory for effects A->D, (EFG)/H dont' share. // Effects Ax and Bx (fine volume slide up and down) require immediate // handling. No flags required. (effect 0 and 1) // Effects Cx, Dx, Ex, Fx (volume/pitch slides) require flag to be // set (effects 2->5) // Effects Gx and Hx need init (handling) code + flags. // (effects 6 and 7). if(ah != 0) { if(al >= 4) { if(al < 6) { // Ex Fx chn->EFG = ah<<2; } else if(al <= 6) { // Gx if((ite->hdr.Flags & 0x0020) != 0) // Link command G? { chn->GOE = SlideTable[ah-1]; } else { chn->EFG = SlideTable[ah-1]; } } } else { // Ax Bx Cx Dx chn->VVal = ah; } } if((chn->Flags & 0x04) != 0) { // Channel not on! // TODO: work out what this comment means and which it applies to // (I think it applies to this block) it_slave *slave = &ite->slave[chn->SCOffst]; if(al <= 1) { if(al != 1) { al = chn->VVal; al += slave->VS; if(al > 64) al = 64; } else { al = chn->VVal; al -= slave->VS; if((al & 0x80) != 0) al = 0; } CommandD2(ite, chn, slave, al); return; } else { chn->Flags |= 0x0100; if(al > 6) { InitVolumeEffectH(ite, chn, ah); return; } else if(al == 6) { InitCommandG11(ite, chn); return; } return; } } else { if(al == 7) InitVolumeEffectH(ite, chn, ah); }} void InitVolumeEffectH(it_engine *ite, it_host *chn, uint8_t ah){ ah <<= 2; if(ah != 0) chn->VDp = ah; if((chn->Flags & 4) != 0) InitVibrato(ite, chn);} void VolumeCommandC(it_engine *ite, it_host *chn){ it_slave *slave = &ite->slave[chn->SCOffst]; uint8_t al = chn->VVal + slave->VS; if(al > 64) { chn->Flags &= ~0x0100; // Turn off effect calling al = 64; } CommandD2(ite, chn, slave, al);} void VolumeCommandD(it_engine *ite, it_host *chn){ it_slave *slave = &ite->slave[chn->SCOffst]; uint8_t al = slave->VS - chn->VVal; //if((al & 0x80) != 0) // JNC, not JNS if(slave->VS < chn->VVal) { chn->Flags &= ~0x0100; // Turn off effect calling al = 0; } CommandD2(ite, chn, slave, al);} void VolumeCommandE(it_engine *ite, it_host *chn) // Pitch slide down{ CommandEChain(ite, chn, ((int16_t)(uint16_t)chn->EFG)<<2);} void VolumeCommandF(it_engine *ite, it_host *chn){ CommandFChain(ite, chn, ((int16_t)(uint16_t)chn->EFG)<<2);} void VolumeCommandG(it_engine *ite, it_host *chn){ if((chn->Flags & 0x16) == 0) return; uint16_t bx = chn->EFG; if((ite->hdr.Flags & 0x0020) != 0) // Link command G? bx = chn->GOE; if(bx == 0) return; bx <<= 2; it_slave *slave = &ite->slave[chn->SCOffst]; if(chn->_42 != 1) { // Slide down PitchSlideDown(ite, chn, slave, bx); // Check that frequency is above porta // to frequency. int32_t eaxs = slave->Frequency; if(eaxs <= chn->Porta_Frequency) { chn->Flags &= ~0x0110; // Turn off calling slave->Frequency = eaxs = chn->Porta_Frequency; } slave->Frequency_Set = eaxs; } else { // Slide up! PitchSlideUp(ite, chn, slave, bx); // Check that // 1) Channel is on // 2) Frequency (set) is below porta to // frequency int32_t eaxs = slave->Frequency; if((slave->Flags & 0x0200) != 0 || eaxs > chn->Porta_Frequency) { slave->Flags &= ~0x0200; chn->Flags |= 0x0004; // Turn on. chn->Flags &= ~0x0110; // Turn off calling slave->Frequency = eaxs = chn->Porta_Frequency; } slave->Frequency_Set = eaxs; }} void InitNoCommand(it_engine *ite, it_host *chn) // DS:DI points to CIT area.{ it_slave *slave; uint8_t cl = chn->Msk; // CL = mask uint8_t ch = chn->Flags; // CH = channel info. if((cl & 0x33) == 0) goto NoOldEffect; // InitCommand1 uint8_t al = chn->Nt2; // Note here! // Check for noteoff. if(al >= 120) { if((ch & 0x04) == 0) // Taken if the channel's off. { // Jump point. goto NoOldEffect; // InitNoCommand1 } slave = &ite->slave[chn->SCOffst]; //if(0) if(al > 0xFE) // Noteoff { slave->Flags |= 0x0004; // Note off // if(slave->VS == 0) // Volume = 0??? // goto InitNoCommand13; } else { //if(al == 0xFE || al == 0xFF) if(al == 0xFE) { ch &= ~4; if(chn->Smp != 100 && (ite->d.DriverFlags & 2) == 0) { slave->Flags = 0x0200; goto NoOldEffect; } // MIDINoteCut: // ch &= ~4; slave->Flags |= 0x0200; } else { slave->Flags |= 8; // Note fade goto NoOldEffect; } } } else { if((ch & 4) != 0 && (cl & 0x11) == 0 && ite->slave[chn->SCOffst].Nte != chn->Nte) goto NoOldEffect; // InitNoCommand1 if((cl & 0x44) != 0 && chn->Vol >= 193 && chn->Vol <= 202 && (chn->Flags & 4) != 0) { InitVolumeEffect(ite, chn); return; } slave = AllocateChannel(ite, chn, &ch); if(slave == NULL) goto NoOldEffect; // Channel allocated. // put volume slave->Vol = slave->VS = chn->VSe; it_sample *smp = &ite->smp[slave->SmpOffs]; if((ite->hdr.Flags & 4) == 0 && (smp->DfP & 0x80) != 0) slave->PS = slave->Pan = chn->CP = smp->DfP & 0x7F; uint32_t eax = smp->C5Speed; slave->OldSampleOffset = 0; slave->SmpErr = 0; slave->Sample_Offset = 0; // Calculate frequency. uint64_t da = (uint64_t)eax * (uint64_t)PitchTable[chn->Nt2]; eax = (uint32_t)(((uint64_t)da)>>(uint64_t)16); slave->Frequency = slave->Frequency_Set = eax; ch |= 4; ch &= ~16; } GetLoopInformation(ite, slave); //InitNoCommand1: if((cl & (0x22 + 0x44)) == 0) goto InitNoCommand3; // Instrument mode and old effects? if((ite->hdr.Flags & 0x14) != 0x14) goto NoOldEffect; if(cl & 0x22) goto NoOldEffect; if(chn->Ins == 0xFF) goto NoOldEffect; slave->FadeOut = 0x0400; InitPlayInstrument(ite, chn, slave, chn->Ins); NoOldEffect: // TODO: fix this dreadful flow code once everything works --GM if((cl & 0x44) == 0) goto InitNoCommand7; if(chn->Vol <= 64) { chn->VSe = chn->Vol; goto InitNoCommand8; // Volume set... } if((chn->Vol & 0x7F) >= 65) goto InitNoCommand7; // Panning set!//InitNoCommandPanning: chn->Flags = (chn->Flags & 0xFF00) | (0xFF & (uint16_t)ch); InitCommandX2(ite, chn, chn->Vol - 128); // Destroys (SI), AX InitNoCommand7: if((cl & 0x22) == 0) // Instrument present? Change volume goto InitNoCommand3; // Get instrument offset. if(chn->Smp == 0xFF) goto InitNoCommand3; chn->VSe = ite->smp[chn->Smp-1].Vol; // Default volume InitNoCommand8: if((ch & 4) == 0) goto InitNoCommand3; slave = &ite->slave[chn->SCOffst]; slave->Vol = slave->VS = chn->VSe; slave->Flags |= 0x10; // recalc volume InitNoCommand3: // Randomise volume if required. if((chn->Flags & 0x80) == 0) { chn->Flags = (chn->Flags & 0xFF00) | (0xFF & (uint16_t)ch); InitVolumeEffect(ite, chn); return; } chn->Flags = (chn->Flags & 0xFF00) | (0xFF & (uint16_t)ch); ApplyRandomValues(ite, chn); InitVolumeEffect(ite, chn);} void InitCommandA(it_engine *ite, it_host *chn){ uint16_t ax = chn->CVal; if(ax != 0) { ite->CurrentTick -= ite->CurrentSpeed; ite->ProcessTick -= ite->CurrentSpeed; ite->CurrentTick += ax; ite->ProcessTick += ax; ite->CurrentSpeed = ax; } InitNoCommand(ite, chn);} void InitCommandB(it_engine *ite, it_host *chn){ uint16_t ax = chn->CVal; if(ax < ite->CurrentOrder) ite->StopSong = 1; ax--; ite->ProcessOrder = ax; ite->ProcessRow = 0xFFFE; InitNoCommand(ite, chn);} void InitCommandC(it_engine *ite, it_host *chn){ if(ite->PatternLooping == 0) { ite->BreakRow = chn->CVal; ite->ProcessRow = 0xFFFE; } InitNoCommand(ite, chn);} void InitCommandD(it_engine *ite, it_host *chn){ InitNoCommand(ite, chn); if(chn->CVal != 0) chn->DKL = chn->CVal; if((chn->Flags & 4) == 0) return; it_slave *slave = &ite->slave[chn->SCOffst]; InitCommandD7(ite, chn, slave);} Lines 1–500 of 2230. Load more
/* Copyright (C) 2014, Jeffrey Lim. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "it_struc.h" uint8_t SlideTable[9] = { 1, 4, 8, 16, 32, 64, 96, 128, 255 }; void InitVolumeEffectH(it_engine *ite, it_host *chn, uint8_t ah); void InitCommandD7(it_engine *ite, it_host *chn, it_slave *slave); void InitCommandG11(it_engine *ite, it_host *chn); void InitCommandX2(it_engine *ite, it_host *chn, uint8_t al); void CommandD2(it_engine *ite, it_host *chn, it_slave *slave, uint8_t al); void CommandEChain(it_engine *ite, it_host *chn, int16_t bx); void CommandFChain(it_engine *ite, it_host *chn, int16_t bx); void InitVibrato(it_engine *ite, it_host *chn); void CommandH5(it_engine *ite, it_host *chn, it_slave *slave, int8_t al); void InitTremelo(it_engine *ite, it_host *chn); void CommandR2(it_engine *ite, it_host *chn, it_slave *slave, int8_t al); /* // Not transcribing further unless there is a good reason to. int32_t GetC5Speed(uint8_t *ds, uint8_t *es, uint16_t bx) { if(*(uint8_t *)(ds + di + 0x0F) == 101) { // OK.. we have a MIDI sample // Check whether the midi sample points to a valid sample // And if so, use that sample's C5 speed. uint16_t si = *(uint8_t *)(ds + di + 0x03); // Not a note? uint32_t ebp = *(uint8_t *)(ds + di + 0x04); if(ebp != 0) // No sample? { si += si; ebp = *(uint16_t *)(es + 64710 + ebp + ebp); uint8_t al = *(uint8_t *)(es + ebp + si + 0x40) // AL = note uint8_t ah = *(uint8_t *)(es + ebp + si + 0x41) // AH = sample. if(ah != 0) // No sample? { si = ah*2; si = *(uint16_t *)(es + 64910 + si) // Sample offset if(*(uint8_t *)(es + si + 0x12) == 1) { bx = si; } } } } return *(uint8_t *)(es + bx + 0x3C); // EAX = C5Spd } */ void InitVolumeEffect(it_engine *ite, it_host *chn) // Done A, B, H { if((chn->Msk & 0x44) == 0) return; uint8_t al = chn->Vol; uint8_t ah = al; al &= 0x7F; if(al < 65) return; al -= 65; if((ah & 0x80) != 0) { al += 60; } uint8_t dl = 10; uint8_t tmpquo = al / dl; uint8_t tmprem = al % dl; al = tmpquo; // Effect number ah = tmprem; // Effect parameter chn->VCm = al; // Store effect number // Memory for effects A->D, (EFG)/H dont' share. // Effects Ax and Bx (fine volume slide up and down) require immediate // handling. No flags required. (effect 0 and 1) // Effects Cx, Dx, Ex, Fx (volume/pitch slides) require flag to be // set (effects 2->5) // Effects Gx and Hx need init (handling) code + flags. // (effects 6 and 7). if(ah != 0) { if(al >= 4) { if(al < 6) { // Ex Fx chn->EFG = ah<<2; } else if(al <= 6) { // Gx if((ite->hdr.Flags & 0x0020) != 0) // Link command G? { chn->GOE = SlideTable[ah-1]; } else { chn->EFG = SlideTable[ah-1]; } } } else { // Ax Bx Cx Dx chn->VVal = ah; } } if((chn->Flags & 0x04) != 0) { // Channel not on! // TODO: work out what this comment means and which it applies to // (I think it applies to this block) it_slave *slave = &ite->slave[chn->SCOffst]; if(al <= 1) { if(al != 1) { al = chn->VVal; al += slave->VS; if(al > 64) al = 64; } else { al = chn->VVal; al -= slave->VS; if((al & 0x80) != 0) al = 0; } CommandD2(ite, chn, slave, al); return; } else { chn->Flags |= 0x0100; if(al > 6) { InitVolumeEffectH(ite, chn, ah); return; } else if(al == 6) { InitCommandG11(ite, chn); return; } return; } } else { if(al == 7) InitVolumeEffectH(ite, chn, ah); } } void InitVolumeEffectH(it_engine *ite, it_host *chn, uint8_t ah) { ah <<= 2; if(ah != 0) chn->VDp = ah; if((chn->Flags & 4) != 0) InitVibrato(ite, chn); } void VolumeCommandC(it_engine *ite, it_host *chn) { it_slave *slave = &ite->slave[chn->SCOffst]; uint8_t al = chn->VVal + slave->VS; if(al > 64) { chn->Flags &= ~0x0100; // Turn off effect calling al = 64; } CommandD2(ite, chn, slave, al); } void VolumeCommandD(it_engine *ite, it_host *chn) { it_slave *slave = &ite->slave[chn->SCOffst]; uint8_t al = slave->VS - chn->VVal; //if((al & 0x80) != 0) // JNC, not JNS if(slave->VS < chn->VVal) { chn->Flags &= ~0x0100; // Turn off effect calling al = 0; } CommandD2(ite, chn, slave, al); } void VolumeCommandE(it_engine *ite, it_host *chn) // Pitch slide down { CommandEChain(ite, chn, ((int16_t)(uint16_t)chn->EFG)<<2); } void VolumeCommandF(it_engine *ite, it_host *chn) { CommandFChain(ite, chn, ((int16_t)(uint16_t)chn->EFG)<<2); } void VolumeCommandG(it_engine *ite, it_host *chn) { if((chn->Flags & 0x16) == 0) return; uint16_t bx = chn->EFG; if((ite->hdr.Flags & 0x0020) != 0) // Link command G? bx = chn->GOE; if(bx == 0) return; bx <<= 2; it_slave *slave = &ite->slave[chn->SCOffst]; if(chn->_42 != 1) { // Slide down PitchSlideDown(ite, chn, slave, bx); // Check that frequency is above porta // to frequency. int32_t eaxs = slave->Frequency; if(eaxs <= chn->Porta_Frequency) { chn->Flags &= ~0x0110; // Turn off calling slave->Frequency = eaxs = chn->Porta_Frequency; } slave->Frequency_Set = eaxs; } else { // Slide up! PitchSlideUp(ite, chn, slave, bx); // Check that // 1) Channel is on // 2) Frequency (set) is below porta to // frequency int32_t eaxs = slave->Frequency; if((slave->Flags & 0x0200) != 0 || eaxs > chn->Porta_Frequency) { slave->Flags &= ~0x0200; chn->Flags |= 0x0004; // Turn on. chn->Flags &= ~0x0110; // Turn off calling slave->Frequency = eaxs = chn->Porta_Frequency; } slave->Frequency_Set = eaxs; } } void InitNoCommand(it_engine *ite, it_host *chn) // DS:DI points to CIT area. { it_slave *slave; uint8_t cl = chn->Msk; // CL = mask uint8_t ch = chn->Flags; // CH = channel info. if((cl & 0x33) == 0) goto NoOldEffect; // InitCommand1 uint8_t al = chn->Nt2; // Note here! // Check for noteoff. if(al >= 120) { if((ch & 0x04) == 0) // Taken if the channel's off. { // Jump point. goto NoOldEffect; // InitNoCommand1 } slave = &ite->slave[chn->SCOffst]; //if(0) if(al > 0xFE) // Noteoff { slave->Flags |= 0x0004; // Note off // if(slave->VS == 0) // Volume = 0??? // goto InitNoCommand13; } else { //if(al == 0xFE || al == 0xFF) if(al == 0xFE) { ch &= ~4; if(chn->Smp != 100 && (ite->d.DriverFlags & 2) == 0) { slave->Flags = 0x0200; goto NoOldEffect; } // MIDINoteCut: // ch &= ~4; slave->Flags |= 0x0200; } else { slave->Flags |= 8; // Note fade goto NoOldEffect; } } } else { if((ch & 4) != 0 && (cl & 0x11) == 0 && ite->slave[chn->SCOffst].Nte != chn->Nte) goto NoOldEffect; // InitNoCommand1 if((cl & 0x44) != 0 && chn->Vol >= 193 && chn->Vol <= 202 && (chn->Flags & 4) != 0) { InitVolumeEffect(ite, chn); return; } slave = AllocateChannel(ite, chn, &ch); if(slave == NULL) goto NoOldEffect; // Channel allocated. // put volume slave->Vol = slave->VS = chn->VSe; it_sample *smp = &ite->smp[slave->SmpOffs]; if((ite->hdr.Flags & 4) == 0 && (smp->DfP & 0x80) != 0) slave->PS = slave->Pan = chn->CP = smp->DfP & 0x7F; uint32_t eax = smp->C5Speed; slave->OldSampleOffset = 0; slave->SmpErr = 0; slave->Sample_Offset = 0; // Calculate frequency. uint64_t da = (uint64_t)eax * (uint64_t)PitchTable[chn->Nt2]; eax = (uint32_t)(((uint64_t)da)>>(uint64_t)16); slave->Frequency = slave->Frequency_Set = eax; ch |= 4; ch &= ~16; } GetLoopInformation(ite, slave); //InitNoCommand1: if((cl & (0x22 + 0x44)) == 0) goto InitNoCommand3; // Instrument mode and old effects? if((ite->hdr.Flags & 0x14) != 0x14) goto NoOldEffect; if(cl & 0x22) goto NoOldEffect; if(chn->Ins == 0xFF) goto NoOldEffect; slave->FadeOut = 0x0400; InitPlayInstrument(ite, chn, slave, chn->Ins); NoOldEffect: // TODO: fix this dreadful flow code once everything works --GM if((cl & 0x44) == 0) goto InitNoCommand7; if(chn->Vol <= 64) { chn->VSe = chn->Vol; goto InitNoCommand8; // Volume set... } if((chn->Vol & 0x7F) >= 65) goto InitNoCommand7; // Panning set! //InitNoCommandPanning: chn->Flags = (chn->Flags & 0xFF00) | (0xFF & (uint16_t)ch); InitCommandX2(ite, chn, chn->Vol - 128); // Destroys (SI), AX InitNoCommand7: if((cl & 0x22) == 0) // Instrument present? Change volume goto InitNoCommand3; // Get instrument offset. if(chn->Smp == 0xFF) goto InitNoCommand3; chn->VSe = ite->smp[chn->Smp-1].Vol; // Default volume InitNoCommand8: if((ch & 4) == 0) goto InitNoCommand3; slave = &ite->slave[chn->SCOffst]; slave->Vol = slave->VS = chn->VSe; slave->Flags |= 0x10; // recalc volume InitNoCommand3: // Randomise volume if required. if((chn->Flags & 0x80) == 0) { chn->Flags = (chn->Flags & 0xFF00) | (0xFF & (uint16_t)ch); InitVolumeEffect(ite, chn); return; } chn->Flags = (chn->Flags & 0xFF00) | (0xFF & (uint16_t)ch); ApplyRandomValues(ite, chn); InitVolumeEffect(ite, chn); } void InitCommandA(it_engine *ite, it_host *chn) { uint16_t ax = chn->CVal; if(ax != 0) { ite->CurrentTick -= ite->CurrentSpeed; ite->ProcessTick -= ite->CurrentSpeed; ite->CurrentTick += ax; ite->ProcessTick += ax; ite->CurrentSpeed = ax; } InitNoCommand(ite, chn); } void InitCommandB(it_engine *ite, it_host *chn) { uint16_t ax = chn->CVal; if(ax < ite->CurrentOrder) ite->StopSong = 1; ax--; ite->ProcessOrder = ax; ite->ProcessRow = 0xFFFE; InitNoCommand(ite, chn); } void InitCommandC(it_engine *ite, it_host *chn) { if(ite->PatternLooping == 0) { ite->BreakRow = chn->CVal; ite->ProcessRow = 0xFFFE; } InitNoCommand(ite, chn); } void InitCommandD(it_engine *ite, it_host *chn) { InitNoCommand(ite, chn); if(chn->CVal != 0) chn->DKL = chn->CVal; if((chn->Flags & 4) == 0) return; it_slave *slave = &ite->slave[chn->SCOffst]; InitCommandD7(ite, chn, slave); }