/* MED-plr.c by Teijo Kinnunen 1989, 1990 */
/* Sisältää: editoinnin */
#include "med.h"

UWORD near periodit[] = { 856,808,762,720,678,640,604,570,538,508,480,453,
			  428,404,381,360,339,320,302,285,269,254,240,226,
			  214,202,190,180,170,160,151,143,135,127,120,113,
			  214,202,190,180,170,160,151,143,135,127,120,113,
			  214,202,190,180,170,160,151,143,135,127,120,113,
			  214,202,190,180,170,160,151,143,135,127,120,113 };
UBYTE firstdisptrk = 0,counter = 0;
extern void __asm PaivitaNaytto(register __d0 UWORD);
struct Library *ciaaresource;
extern struct Gadget far gadget6[];
extern struct Kappale far tamakappale;
extern struct RastPort *wrp;
extern UWORD volatile soittorivi,soittolohko,soittotila;
extern UWORD kursorix,currtrk,soittimennum,lohkoja,currpos;
extern struct Lohko far *lohko[];
static UBYTE far instrcode[] = { 0x0a,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
				0x09,0x20,0x35,0x33,0x22,0x12,0x23,0x24,0x25,
				0x17,0x26,0x27,0x28,0x37,0x36,0x18,0x19,0x10,
				0x13,0x21,0x14,0x16,0x34 };
static UBYTE far fastnotenum = 0;
static BYTE far kbnotes[] = {
	-1,-1,13,15,-1,18,20,22,-1,25,27,-1,30,32,-1,-1,
	12,14,16,17,19,21,23,24,26,28,29,31,-1,-1,-1,-1,
	-1,1,3,-1,6,8,10,-1,13,15,-1,-1,-1,-1,-1,-1,
	-1,0,2,4,5,7,9,11,12,14,16 }; /* end = 0x3a */
static UBYTE far fastnotes[10][3];
UBYTE far nappkoodi[]={ 0x31,0x21,0x32,0x22,0x33,0x34,0x24,0x35,0x25,0x36,0x26,
			0x37,
			0x10,0x02,0x11,0x03,0x12,0x13,0x05,0x14,0x06,0x15,0x07,
			0x16 };
static UWORD chip zerodata = 0;
UWORD far nappokt = 0,editline,*zeroptr = &zerodata;
static UBYTE far lfx0,far lfx1,far rfx0,far rfx1;
struct MEDSoftIntCmd komento;
extern UWORD nykyinenosio;

static void PlayNote(UBYTE notenum,UWORD instr)
{
	komento.msic_data = (ULONG)notenum;
	komento.msic_soitin = instr;
	komento.msic_aani = currtrk;
	komento.msic_cmd = SOITANUOTTI;
	SetICR(ciaaresource,CIAICRF_SETCLR|CIAICRF_TA);
}
	
static void UpdateScreen()
{
	if(soittotila == ALASOITA && (gadget6[25].GadgetID & 0x1000))
		soittorivi++;
	if(soittorivi > 63) { soittorivi = 0; PaivitaNaytto(TRUE); }
	else PaivitaNaytto(1234); /* secret code */
}
	
static UBYTE *CalcOffs(block,line,track)
UWORD block,line,track;
{
	if(block > lohkoja - 1) return(0);
	if(track > lohko[block]->numtracks - 1) return(0);
	return(&lohko[block]->music[line * lohko[block]->numtracks * 3 +
		3 * track]);
}

static void PutNote(block,line,track,note,instr)
UWORD block,line,track;
UBYTE note;
UWORD instr;
{
	UBYTE *putptr = CalcOffs(block,line,track);
	if(!putptr) return;
	*putptr = note;
	if(instr > 0xF) *putptr |= 0x80;
	*(putptr+1) = (*(putptr + 1) & 0x0F) | (instr << 4);
}

static void PutData(block,line,track,num,val)
UWORD block,line,track;
UBYTE num,val;
{
	UBYTE *putptr = CalcOffs(block,line,track);
	if(!putptr) return;
	switch(num) {
	    case 0:
		*(putptr+1) = (*(putptr + 1) & 0x0F) | (val << 4);
		if(val > 0xF) *putptr |= 0x80; else *putptr &= ~0x80;
		break;
	    case 1:
	    	*(putptr+1) = (*(putptr + 1) & 0xF0) | val;
		break;
	    case 2:
	    	*(putptr+2) = (*(putptr + 2) & 0x0F) | (val << 4);
		break;
	    case 3:
	    	*(putptr+2) = (*(putptr + 2) & 0xF0) | val;
		break;
	}
}

void SoitaNappain(UWORD code,BOOL canberecursive,UWORD qual)
{
	UBYTE notenum = 0,whichnum,keycount,callagain = FALSE,*thisnote;
	UWORD edblock = soittolohko; /* soittolohko is volatile!! */
	BYTE num = -1;
	static UBYTE extraoffs[4] = { 8,17,26,35 };
	editline = soittorivi;
	if(code <= 0x3a && kbnotes[code] != -1)
		notenum =  nappokt * 12 + kbnotes[code] + 1;
	if(notenum > 63) return;
	if(gadget6[0].GadgetID & 0x1000) {
	    if(kursorix == 4||kursorix == 13||kursorix == 22||
	    	kursorix == 31) {
			callagain = TRUE;
			if(notenum) PutNote(edblock,editline,
				currtrk,notenum,soittimennum);
			else if(code == 0x46) PutNote(edblock,editline,
				currtrk,0,0); /* DEL */
			else callagain = FALSE;
			if(callagain && (qual & (ALTLEFT|ALTRIGHT))) {
				thisnote = CalcOffs(edblock,editline,currtrk);
				if(thisnote) {
					*(thisnote+1) &= 0xf0;
					if(qual & ALTLEFT) {
						*(thisnote+1) |= lfx0;
						*(thisnote+2) = lfx1;
					} else {
						*(thisnote+1) |= rfx0;
						*(thisnote+2) = rfx1;
					}
				}
			}
	    } else {
		whichnum = kursorix - extraoffs[currpos];
		for(keycount = 0; keycount < 32; keycount++)
			if(code == instrcode[keycount]) { num = keycount; break; }
		if(code == 0x46) num = 0;
		if(num > 0xF && whichnum) num = -1; /* G-V only in # 1 */
		if(num != -1) PutData(edblock,editline,currtrk,
			whichnum,num);
	    }
	    if(notenum || num != -1 || code == 0x46) UpdateScreen();
	}
	if(notenum && num == -1) PlayNote(notenum,soittimennum);
	if((gadget6[1].GadgetID & 0x1000) && callagain && canberecursive)
		SoitaNappain(0x46,FALSE,qual); /* DEL, can't be recursive */
}

void PutMNote(UBYTE note)
{
	editline = soittorivi;
	if(note < 24 || note > 86) return;
	note -= 23;
	if(gadget6[0].GadgetID & 0x1000) {
		PutNote(soittolohko,editline,currtrk,note,soittimennum);
		UpdateScreen();
	}
	if(!tamakappale.midikanava[soittimennum]) PlayNote(note,soittimennum);
	if(gadget6[1].GadgetID & 0x1000) SoitaNappain(0x46,FALSE,0);
}

void DispFNnum()
{
	UBYTE fndisp;
	if(nykyinenosio == 6) {
		SetAPen(wrp,0);
		Move(wrp,19,46);
		fndisp = fastnotenum + '0';
		Text(wrp,&fndisp,1);
	}
}

static void GetFNote(UBYTE nbr)
{
	UBYTE *thisnote = CalcOffs(soittolohko,editline = soittorivi,currtrk);
	if(!thisnote) return; /* shouldn't happen */
	fastnotes[nbr][0] = *thisnote;
	fastnotes[nbr][1] = *(thisnote + 1);
	fastnotes[nbr][2] = *(thisnote + 2);
}

void EditHandler(gid)	/* this is a local gadget-handler */
UWORD gid;
{
	UBYTE *thisnote = CalcOffs(soittolohko,editline = soittorivi,currtrk);
	if(gid == 0x617 && fastnotenum) { fastnotenum--; DispFNnum(); }
	else if(gid == 0x618 && fastnotenum < 9) { fastnotenum++; DispFNnum(); }
	else if(gid == 0x61C && thisnote) GetFNote(fastnotenum);
	else if(gid >= 0x01 && gid <= 0x0A && thisnote) { /* Shift + 0-9 */
		if(gid == 0x0A) gid = 0;
		if(gadget6[0].GadgetID & 0x1000) {
			*thisnote = fastnotes[gid][0];
			*(thisnote + 1) = fastnotes[gid][1];
			*(thisnote + 2) = fastnotes[gid][2];
			UpdateScreen();
			if(gadget6[1].GadgetID & 0x1000)
				SoitaNappain(0x46,FALSE,0);
		}
		if(fastnotes[gid][0] & 0x7f) PlayNote((UBYTE)(fastnotes
			[gid][0] & 0x7f),(UWORD)((fastnotes[gid][1] >> 4) +
			(fastnotes[gid][0] & 0x80 ? 16 : 0)));
	}
	else if(gid == 0x61A && thisnote) {
		lfx0 = *(thisnote+1) & 0x0f; lfx1 = *(thisnote+2); }
	else if(gid == 0x61B && thisnote) {
		rfx0 = *(thisnote+1) & 0x0f; rfx1 = *(thisnote+2); }
	else if(gid >= 0x101 && gid <= 0x10A)
		GetFNote((UBYTE)(gid == 0x10A ? 0 : gid - 0x100));
	else if(gid == 0x46 && gadget6[0].GadgetID & 0x1000) {
		*thisnote = *(thisnote + 1) = *(thisnote + 2) = 0;
		UpdateScreen();
		if(gadget6[1].GadgetID & 0x1000) SoitaNappain(0x46,FALSE,0);
	}
}
