Sigrid Solveig Haflínudóttirfirst69b97135 years agoHistory
2230 lines · 41.5 KB · C
RawDownload
/*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.

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