/* ============================================================================= ptfield.c -- MIDAS-VII patch display field functions Version 35 -- 1989-11-16 -- D.N. Lynx Crowe ============================================================================= */ #define DEBUGXP 0 #define USEVECTR 0 /* to force vector cursor control */ #include "stddefs.h" #include "hwdefs.h" #include "graphdef.h" #include "vsdd.h" #include "fields.h" #include "curpak.h" #include "patch.h" #include "macros.h" #include "midas.h" #include "ptdisp.h" #if DEBUGXP extern short debugsw; short debugxp = 1; #endif #if USEVECTR short usevect = TRUE; extern short (*cx_key)(), (*cy_key)(); #endif extern short (*xy_up)(), (*xy_dn)(); extern short (*premove)(), (*pstmove)(); extern short (*curtype)(); extern unsigned fromfpu(unsigned fputime); extern void select(void); extern short nokey(void); extern short stdctp5(void); extern void cxkstd(void); extern void cykstd(void); extern void stdmkey(void); extern void stddkey(void); extern void stopcm(void); extern void smxupd(void); extern void smyupd(void); extern void aftercm(void); extern void ptdkey(void); extern short astat; extern short chtime; extern short chwait; extern short cmfirst; extern short cmtype; extern short curhold; extern short cvtime; extern short cvwait; extern short ncvwait; extern short ptbflag; extern short ptecpos; extern short ptedef; extern short ptedfok; extern short pteset; extern short ptestm; extern short ptestok; extern short ss_ptsw; extern short ss_sqsw; extern short stccol; extern short stcrow; extern short syrate; extern short tvcwval; extern short vcwval; extern short crate1[]; extern char ptdebuf[]; extern struct selbox *csbp; extern struct selbox ptboxes[]; extern struct patch ptebuf; void ptxkey(void); void ptmkey(void); void ptekey(void); /* */ char *trdata[] = { "Trans", "Stop ", "Start" }; char *ssdata[] = { "Stop ", "Start" }; char *stdata[] = { "Srce" , "Mult", "Time", "Valu", "Func" }; char *smdata[] = { " ", /* SM_NONE 0 No source - always 0 */ "Randm", /* SM_RAND 1 Random source */ "GPC/V", /* SM_CTL1 2 Control Voltage 1 / MIDI GPC 1 */ "??3??", /* ------- 3 -unused- */ "??4??", /* ------- 4 -unused- */ "Pitch", /* SM_PTCH 5 Key Pitch */ "KeyPr", /* SM_KPRS 6 Key Pressure */ "KeyVL", /* SM_KVEL 7 Key Velocity */ "Pedal", /* SM_PED1 8 Pedal 1 */ "??9??", /* ------- 9 -unused- */ "Freq ", /* SM_FREQ 10 Key Frequency */ "PchWh", /* SM_HTPW 11 Tablet X / MIDI Pitch Wheel */ "ModWh", /* SM_VTMW 12 Tablet Y / MIDI Mod Wheel */ "Breth", /* SM_LPBR 13 LongPot / MIDI Breath Controller */ }; struct curpak pt_flds = { stdctp5, /* curtype */ nokey, /* premove */ aftercm, /* pstmove */ cxkstd, /* cx_key */ cykstd, /* cy_key */ smxupd, /* cx_upd */ smyupd, /* cy_upd */ stopcm, /* xy_up */ nokey, /* xy_dn */ ptxkey, /* x_key */ ptekey, /* e_key */ ptmkey, /* m_key */ ptdkey, /* d_key */ nokey, /* not_fld */ (struct fet *)NULL, /* curfet */ ptboxes, /* csbp */ crate1, /* cratex */ crate1, /* cratey */ CT_SMTH, /* cmtype */ CTOX(2), /* cxval */ RTOY(DATAROW) /* cyval */ }; /* */ /* ============================================================================= ptmkey() -- M key processing for the patch display ============================================================================= */ void ptmkey(void) { register short nc; if (astat) { if (stccol EQ 48) { if (ss_sqsw EQ 0) { (*xy_dn)(); /* handle KEY_DOWN functions */ (*premove)(); /* handle PRE-MOVE functions */ nc = (*curtype)(); /* get new CURSOR TYPE wanted */ cvtime = syrate; ncvwait = curhold; ss_ptsw = -1; cmtype = nc; cvwait = 1; } } else stdmkey(); } else { if (stccol EQ 48) { ss_ptsw = 0; cvwait = 1; ncvwait = cvtime; cmfirst = TRUE; if (ss_sqsw EQ 0) (*xy_up)(); (*pstmove)(); /* handle POST-MOVE functions */ } else stdmkey(); } } /* */ /* ============================================================================= ptekey() -- E key processing for the patch display ============================================================================= */ void ptekey(void) { register short nc; if (astat) { if (stccol EQ 48) { if (ss_sqsw EQ 0) { (*xy_dn)(); /* handle KEY_DOWN functions */ (*premove)(); /* handle PRE-MOVE functions */ nc = (*curtype)(); /* get new CURSOR TYPE wanted */ cvtime = syrate; ncvwait = curhold; ss_ptsw = 1; cmtype = nc; cvwait = 1; } } else select(); } else { if (stccol EQ 48) { ss_ptsw = 0; cvwait = 1; ncvwait = cvtime; cmfirst = TRUE; if (ss_sqsw EQ 0) (*xy_up)(); (*pstmove)(); /* handle POST-MOVE functions */ } else select(); } } /* */ /* ============================================================================= ptxkey() -- X key processing for the patch display ============================================================================= */ void ptxkey(void) { register short i, cp, pp, sp, stm; if (NOT astat) /* only on key closures ... */ return; if (inrange(stccol, 2, 13)) { /* definer -- clear definer */ if (ptecpos AND NOT ptbflag) { /* refresh data entry stuff */ memcpyw(&ptebuf.defnum, &patches[ptecpos].defnum, 6); pteset = TRUE; pte2buf(); } ptedef = NULL_DEF; ptedfok = TRUE; memset(&ptdebuf[2], ' ', 12); for (i = 0; i < 48; i++) if (ptdebuf[i] EQ '\0') ptdebuf[i] = ' '; ptdebuf[0] = '\260'; ptdebuf[48] = '\0'; UpdVid(7, 0, ptdebuf, PTEATR); movectc(stcrow, stccol); /* */ } else if (inrange(stccol, 15, 26)) { /* stimulus -- clear stimulus */ if (ptecpos AND NOT ptbflag) { /* refresh data entry stuff */ memcpyw(&ptebuf.defnum, &patches[ptecpos].defnum, 6); pteset = TRUE; pte2buf(); } ptestm = NULL_DEF; ptestok = FALSE; memset(&ptdebuf[15], ' ', 12); for (i = 0; i < 48; i++) if (ptdebuf[i] EQ '\0') ptdebuf[i] = ' '; ptdebuf[0] = '\260'; ptdebuf[48] = '\0'; UpdVid(7, 0, ptdebuf, PTEATR); movectc(stcrow, stccol); } else if (inrange(stccol, 28, 40)) { /* destination -- clear line */ voidpb(); /* void the patch buffer */ ptdebuf[0] = '\260'; ptdebuf[48] = '\0'; UpdVid(7, 0, ptdebuf, PTEATR); movectc(stcrow, stccol); /* */ } else if (inrange(stccol, 42, 46)) { /* datum -- delete the patch */ if (ptecpos) { cp = ptecpos; /* setup indices */ pp = patches[cp].prevstm; sp = patches[cp].nextstm; stm = patches[cp].stmnum; /* get stimulus used */ #if DEBUGXP if (debugsw AND debugxp) printf("ptxkey(): DELETING PATCH pp = %d cp = %d sp = %d\n", pp, cp, sp); #endif if (pp) /* adjust predecessor */ patches[pp].nextstm = sp; else /* adjust stmptr */ stmptr[TRG_MASK & stm] = sp; if (sp) /* adjust successor */ patches[sp].prevstm = pp; if (sp = findnxt(cp)) /* adjust ptecpos */ ptecpos = sp; else if (pp = findprv(cp)) ptecpos = pp; else ptecpos = 0; pt_del(cp); /* delete the patch entry */ /* */ for (i = 0; i < NDEFSTMS; ++i) { /* adjust defptr list */ if (cp = defptr[i]) { /* in use ? */ pp = 0; /* initial predecessor */ while (cp) { /* check the chain */ sp = defents[cp].nextdef; /* successor */ if (defents[cp].stm EQ stm) { #if DEBUGXP if (debugsw AND debugxp) { printf("ptxkey(): DELETING DEF trg=$%04.4X stm=$%04.4X\n", i, stm); printf("ptxkey(): DELETING DEF pp=%d cp=%d sp=%d\n", pp, cp, sp); } #endif if (pp) /* adjust predecessor */ defents[pp].nextdef = sp; else /* adjust defptr */ defptr[i] = sp; dt_del(cp); /* delete def entry */ } else { pp = cp; /* update predecessor index */ } cp = sp; /* next defent */ } } } dptw(); /* update the display */ } } } /* */ /* ============================================================================= dspdfst() -- convert a patch DEF or STM value for display ============================================================================= */ void dspdfst(char *buf, unsigned short val) { register unsigned short chan, port, stim; if (val EQ NULL_DEF) { /* handle possible blank definer */ strcpy(buf, " "); return; } port = (val >> 11) & 0x0003; chan = (val >> 7) & 0x000F; stim = val & 0x007F; switch (port) { /* use port to decode possible types */ case 0: /* MIDI-1 - Keys */ case 1: /* MIDI-2 - Keys */ sprintf(buf, "%s %03u %u %02u", (val & 0x8000) ? "Rel" : "Key", 1 + stim, 1 + port, 1 + chan); break; /* */ case 2: /* Local Keys */ switch (chan) { /* use channel to further decode */ case 0: /* Keys - Local Keyboard */ sprintf(buf, "%s %03u L ", (val & 0x8000) ? "Rel" : "Key", 1 + stim); break; case 2: /* Triggers */ sprintf(buf, "Trig %02u ", 1 + stim); break; case 3: /* Pulses */ sprintf(buf, "Pulse %u ", 1 + stim); break; default: /* spurious type -- shouldn't happen */ sprintf(buf, "%s?? %03u L %02u", (val & 0x8000) ? "r" : "c", 1 + stim, 1 + chan); break; } break; default: /* spurious port -- should never happen */ sprintf(buf, "??? %03u %u %02u", 1 + stim, 1 + port, 1 + chan); break; } } /* */ /* ============================================================================= dfpdat() -- convert FPU datum for display ============================================================================= */ char *dfpdat(struct patch *pp) { static char buf[32]; unsigned short sgn, vp1, vp2; short val; val = pp->padat2; switch (pp->padat1) { case PSA_SRC: /* source */ strcpy(buf, smdata[val]); break; case PSA_MLT: /* multiplier */ fr2dec(val, ebuf); buf[0] = ebuf[3]; buf[1] = ebuf[0]; buf[2] = '.'; buf[3] = ebuf[1]; buf[4] = ebuf[2]; buf[5] = '\0'; break; /* */ case PSA_VAL: /* value */ val >>= 5; if (val < 0) { val = -val; sgn = '-'; } else { sgn = '+'; } vp1 = val / 100; vp2 = val - (vp1 * 100); if (vp1 > 9) { vp1 = 0; if (sgn EQ '+') sgn = '\240'; else sgn = '\241'; } sprintf(buf, "%c%u.%02u", sgn, vp1, vp2); break; /* */ case PSA_TIM: /* time */ vp1 = fromfpu(val); sprintf(buf, "%5u", vp1); break; case PSA_FNC: /* function / control */ if ((PE_SPEC & pp->paspec) EQ PA_AUX) sprintf(buf, "%s", (val & 0x0001) ? "On " : "Off "); else sprintf(buf, "%s", (val & 0x0001) ? "Start" : "Stop "); break; default: sprintf(buf, "$%04.4X", val); break; } return(buf); } /* */ /* ============================================================================= pafpu1() -- convert patch for display -- aaaaa ssss tn ddddd Level, Filtr, Fil Q, Loctn, Dynmc ============================================================================= */ void pafpu1(char *bf, char *ad, unsigned short gt, unsigned short gn, struct patch *pp) { sprintf(bf, "%s %s %c%c %s", ad, stdata[pp->padat1], gt, gn, dfpdat(pp)); } /* ============================================================================= pafpu2() -- convert patch for display -- aaa n ssss tn ddddd Index, Freq ============================================================================= */ void pafpu2(char *bf, char *ad, unsigned short os, unsigned short gt, unsigned short gn, struct patch *pp) { sprintf(bf, "%s %d %s %c%c %s", ad, os, stdata[pp->padat1], gt, gn, dfpdat(pp)); } /* ============================================================================= pafpu3() -- convert patch for display -- aaaaa ssss ddddd Aux, Rate, Inten, Depth, Vlt ============================================================================= */ void pafpu3(char *bf, char *ad, struct patch *pp) { sprintf(bf, "%s %s %s", ad, stdata[pp->padat1], dfpdat(pp)); } /* */ /* ============================================================================= dspdest() -- convert patch destination and datum for display ============================================================================= */ void dspdest(char *buf, struct patch *pp) { unsigned short chan, osc, port, stim, vg, vgt, vgn, vp1, vp2, sgn; short val; char buf2[16], *rtype; port = (pp->pasuba >> 11) & 0x0003; /* for trg types */ chan = (pp->pasuba >> 7) & 0x000F; stim = pp->pasuba & 0x007F; vg = (pp->pasuba >> 8) & 0x00FF; /* for vg types */ osc = (pp->pasuba & 0x00FF) + 1; if (vg > 11) { vgt = 'G'; vgn = vg - 11; } else { vgt = 'V'; vgn = vg + 1; } vgn = vgn + ((vgn > 9) ? '\242' : '0'); /* */ switch (PE_SPEC & pp->paspec) { case PA_KEY: /* key action */ sprintf(buf, "K %03u %u %02u %s", 1 + stim, 1 + port, 1 + chan, trdata[pp->padat2 & 0x0003]); break; case PA_TRG: sprintf(buf, "Trigger %02u %s", 1 + stim, ssdata[pp->padat2 & 0x0001]); break; case PA_PLS: sprintf(buf, "Pulse %u %s", 1 + stim, trdata[pp->padat2 & 0x0003]); break; /* */ case PA_LED: if (pp->pasuba & 0x0001) { sprintf(buf, "LED %c %c%c%c%c", 'A' + pp->pasuba, '0' + ((pp->padat1 >> 14) & 0x0003), '0' + ((pp->padat1 >> 12) & 0x0003), '0' + ((pp->padat1 >> 10) & 0x0003), '0' + ((pp->padat1 >> 8) & 0x0003)); } else { sprintf(buf, "LED %c %c%c%c", 'A' + pp->pasuba, '0' + ((pp->padat1 >> 14) & 0x0003), '0' + ((pp->padat1 >> 12) & 0x0003), '0' + ((pp->padat1 >> 10) & 0x0003)); } break; case PA_SLIN: sprintf(buf, "Seq %02u Lin %03u", 1 + pp->pasuba, pp->padat1); break; case PA_SCTL: sprintf(buf, "Seq %02u Ctl %s", 1 + pp->pasuba, ssdata[pp->padat2 & 0x0001]); break; case PA_TUNE: sprintf(buf, "Tune Table %u", pp->padat1); break; /* */ case PA_RSET: rtype = "Set"; goto doregs; case PA_RADD: rtype = "Add"; doregs: if (pp->padat1 & 0x0001) { sprintf(buf, "Reg %02u %s R%02u", 1 + pp->pasuba, rtype, 1 + pp->padat2); } else { if ((val = pp->padat2) < 0) { sgn = '-'; val = - val; } else { sgn = '+'; } sprintf(buf, "Reg %02u %s %c%02u", 1 + pp->pasuba, rtype, sgn, val); } break; case PA_INST: sprintf(buf, "Instrument %c%c %02u", vgt, vgn, pp->padat1); break; /* */ case PA_OSC: val = pp->padat2 >> 1; switch (pp->padat1) { case PSO_INT: /* interval */ if (val < 0) { sgn = '-'; val = -val; } else { sgn = '+'; } sprintf(buf, "Osc %u Int %c%c %c%04u", osc, vgt, vgn, sgn, val); break; case PSO_RAT: /* ratio */ int2rat(val); sprintf(buf, "Osc %u Rat %c%c %s", osc, vgt, vgn, ebuf); break; case PSO_FRQ: /* frequency */ vp1 = val / 10; vp2 = val - (vp1 * 10); sprintf(buf, "Osc %u Frq %c%c %02u.%u", osc, vgt, vgn, vp1, vp2); break; /* */ case PSO_PCH: /* pitch */ cnvc2p(ebuf, val); sprintf(buf, "Osc %u Pch %c%c %s", osc, vgt, vgn, ebuf); break; default: break; } break; /* */ case PA_WAVA: sgn = 'A'; goto dowaves; case PA_WAVB: sgn = 'B'; dowaves: sprintf(buf, "Waveshape%c %c%c %02u", sgn, vgt, vgn, pp->padat1); break; case PA_CNFG: sprintf(buf, "Configure %c%c %02u", vgt, vgn, pp->padat1); break; /* */ case PA_LEVL: pafpu1(buf, "Level", vgt, vgn, pp); break; case PA_INDX: pafpu2(buf, "Ind", osc, vgt, vgn, pp); break; case PA_FREQ: pafpu2(buf, "Frq", osc, vgt, vgn, pp); break; case PA_FILT: pafpu1(buf, "Filtr", vgt, vgn, pp); break; case PA_FILQ: pafpu1(buf, "Fil Q", vgt, vgn, pp); break; case PA_LOCN: pafpu1(buf, "Loctn", vgt, vgn, pp); break; case PA_DYNM: pafpu1(buf, "Dynmc", vgt, vgn, pp); break; /* */ case PA_AUX: pafpu3(buf, "Aux ", pp); break; case PA_RATE: pafpu3(buf, "Rate ", pp); break; case PA_INTN: pafpu3(buf, "Inten", pp); break; case PA_DPTH: pafpu3(buf, "Depth", pp); break; case PA_VOUT: sprintf(buf2, "Vlt %u", pp->pasuba); pafpu3(buf, buf2, pp); break; default: break; } } /* */ /* ============================================================================= ptfield() -- setup field routines for the patch editor ============================================================================= */ void ptfield(void) { curset(&pt_flds); #if USEVECTR if (usevect) { cx_key = cxkstd; cy_key = cykstd; } #endif }