This is FakePatchPoint.m in view mode; [Download] [Up]
/**************************************************
* SynthBuilder
* Copyright 1993 Nick Porcaro All Rights Reserved
**************************************************/
/* #define DEBUG_ERASE 1 */
/*
* FakePatchPoint.m
* Eric Jordan, independent work, Spring, 1992
*/
#import <stdlib.h>
#import <stdio.h>
#import <appkit/Application.h>
#import <appkit/Control.h>
#import <appkit/Slider.h>
#import <musickit/musickit.h>
#import "FakePatchPoint.h"
#import "FakeSynthPatch.h"
#import "PatchParam.h"
#import "Clavier.h"
#import "FakeUG.h"
#import <dsp/DSPConversion.h>
#import "Utilities.h"
extern char *getAppName();
@implementation FakePatchPoint
static char TempString[1024];
+ initialize
/* Set the version. This can be used in a later version to distinguish older
* formats when unarchiving documents.
*/
{
[FakePatchPoint setVersion:3];
return self;
}
- awakeFromNib
{
clickCount = 0;
midiConnected = NO;
return self;
}
- init
{
[super init];
toNode = [[List alloc] init];
allocOrder = 1;
isAllocated = NO;
strcpy(theName,"");
clickCount = 0;
useInspectorRect = NO;
inspectorRectJustLoaded = NO;
midiConnected = NO;
return self;
}
- setSP:aSP
{
theSP = aSP;
return self;
}
- closeInspector
{
[inspector performClose:self];
inspectorDisplayed = NO;
return self;
}
- setName:(char *) aName
{
if (! aName)
{
return nil;
}
if (! [[theSP utilities] checkName:aName])
{
if (inspector)
{
[ppNameField setStringValue:theName];
}
return nil;
}
strcpy(theName, aName);
return self;
}
- takeAllocOrderFrom:sender
{
int button, order, ival, maxOrder;
maxOrder = [[theSP getFakePatchPoints] count];
order = [self getAllocOrder];
if ([sender isKindOfClassNamed: "TextField"])
{
ival = [sender intValue];
if ((ival <= maxOrder) && (ival >=1))
{
[self setAllocOrder:order];
[theSP sortFakePatchPointsByAllocOrder];
[self updateAllocOrder];
}
else
{
NXRunAlertPanel(getAppName(), "Invalid order: %d Must be between 1 and %d",
NULL, NULL, NULL, ival, maxOrder);
[sender setIntValue:order];
return self;
}
}
else
{
/* Get order from switcher */
/* button = 1 for top, -1 for botton */
button = [[sender selectedCell] tag];
order += button;
/* Only set a new order if it's within range */
if ((order <= maxOrder) && (order >= 1))
{
[self setAllocOrder:order];
[theSP sortFakePatchPointsByAllocOrder];
[self updateAllocOrder];
}
}
return self;
}
- setAllocOrder:(int) order
{
allocOrder = order;
return self;
}
- (int) getAllocOrder
{
return allocOrder;
}
- updateAllocOrder
{
[allocOrderField setIntValue:allocOrder];
return self;
}
- displayInspector
{
if (! inspector)
{
[NXApp loadNibSection:"FakePatchPoint.nib" owner:self withNames:NO];
}
[ppNameField setStringValue:theName];
[self updateAllocOrder];
[self setInspectorName: theName];
[self updateInfo];
if (inspectorRectJustLoaded)
{
if (useInspectorRect)
{
[inspector placeWindowAndDisplay:&inspectorRect];
useInspectorRect = NO;
}
inspectorRectJustLoaded = NO;
}
/* doHighlight toggle prevents the instance
* from being highlighted twice
*/
doHighlight = NO;
[inspector makeKeyAndOrderFront:self];
doHighlight = YES;
inspectorDisplayed = YES;
return self;
}
- displayInspectorIfWasActive
{
if (inspectorDisplayed)
{
[self displayInspector];
}
return self;
}
- updateInfo
{
int i;
id aFakeUG, aToNode;
static char fromStr[256], toStr[256];
char *ptr;
int count;
aFakeUG = [fromNode superview];
ptr = [aFakeUG getMethod:[fromNode getTag]];
if (ptr)
{
sprintf(fromStr, "%s %s", [aFakeUG getName], ptr);
}
else
{
sprintf(fromStr, "%s", [aFakeUG getName]);
}
[fromInfo setStringValue:fromStr];
strcpy(toStr, "");
count = [toNode count];
for (i=0; i<count; i++)
{
aToNode = [toNode objectAt:i];
aFakeUG = [aToNode superview];
ptr = [aFakeUG getMethod:[aToNode getTag]];
if (ptr)
{
sprintf(TempString, "%s %s", [aFakeUG getName], ptr);
}
else
{
sprintf(TempString, "%s", [aFakeUG getName]);
}
strcat(toStr, TempString);
if (i < (count - 1))
{
strcat(toStr, ", ");
}
}
[toInfo setStringValue:toStr];
return self;
}
- inspectorClosed
/* Called by the inspector's delegate */
{
inspectorDisplayed = NO;
return self;
}
- setInspectorName:(char *) aName
{
[inspector setTitle: aName];
return self;
}
- validate
{
int i;
id aToNode;
[fromNode setPatch: theSP];
for (i=0; i<[toNode count]; i++)
{
aToNode = [toNode objectAt:i];
[aToNode setPatch: theSP];
[self checkMidiFrom:[fromNode superview] To:[aToNode superview]];
}
return self;
}
-connect:newFromNode to:newToNode xmemory:(BOOL)mem
{
id fromFakeUG, toFakeUG;
fromFakeUG = [newFromNode superview];
toFakeUG = [newToNode superview];
if ( ([fromFakeUG isClavier] && [toFakeUG isPatchParameter]))
{
id nr;
[[fromFakeUG clavier] connectNoteSenderTo:
[[toFakeUG patchParam] noteReceiver]];
// This bologna is because we have to make sure noteOnHandler is last thing
nr = [[[fromFakeUG clavier] noteOnHandler] noteReceiver];
[[[fromFakeUG clavier] noteSender] disconnect:nr];
[[[fromFakeUG clavier] noteSender] connect:nr];
}
/* Make sure we don't connect event UGs to non-event UGs */
if ( ([fromFakeUG isClavier] && ! [toFakeUG isPatchParameter]) ||
([fromFakeUG isMidi] && ! [toFakeUG isPatchParameter]) )
{
return self;
}
if (! [self checkMidiFrom:fromFakeUG To:toFakeUG])
{
return nil;
}
if (!fromNode)
{
fromNode = newFromNode;
xmemory = mem;
}
[toNode addObject:newToNode];
return self;
}
- checkMidiFrom:aFromFakeUG To:aToFakeUG
{
id midi;
// if ([aFromFakeUG isMidi] && [aToFakeUG isPatchParameter] && ! midiConnected)
if ([aFromFakeUG isMidi] && [aToFakeUG isPatchParameter])
{
id nr;
if (! [theSP initMidi])
{
return nil;
}
midi = [theSP midi];
[midi setMergeInput:YES];
// or [midi channelNoteSender:1] and no setMergeInput
[[midi noteSender] connect:[[aToFakeUG patchParam] noteReceiver]];
nr = [[theSP midiNoteOnHandler] noteReceiver];
[[midi noteSender] disconnect:nr];
[[midi noteSender] connect:nr];
midiConnected = YES;
}
return self;
}
-(FakeUG *)getFromFakeUG
{
return [fromNode superview];
}
-(int)getFromConnectionNumber
{
return [fromNode getTag];
}
-getFromNode
{
return fromNode;
}
-getToNodes
{
return toNode;
}
-(BOOL)getXMemory
{
return xmemory;
}
-(char *)getName
{
return theName;
}
-getpp
{
return pp;
}
- takeNameFromInspector:sender
{
[self setName:(char *) [sender stringValue]];
[ppNameField setStringValue: [sender stringValue]];
[self setInspectorName: theName];
return self;
}
-(char *)getTypeString
{
if ([[fromNode superview] isData])
if (xmemory)
return "xData";
else
return "yData";
if (xmemory)
return "xPatch";
else
return "yPatch";
}
-(BOOL)isAFakeUG
{
return NO;
}
-(BOOL)isAFakePatchPoint
{
return YES;
}
-(BOOL)isPatchParameter
{
return NO;
}
-(BOOL)isClavier
{
return NO;
}
-(BOOL)isMidi
{
return NO;
}
-allocatePPMK
{
int i;
id toFakeUG;
id fromFakeUG;
id midi;
if (isAllocated)
{
return self;
}
/* Nasty hack for putting Claviers/Midi/PatchParameter back together again */
fromFakeUG = [fromNode superview];
if ( [fromFakeUG isClavier] || [fromFakeUG isMidi])
{
for (i=0; i<[toNode count]; i++)
{
toFakeUG = [[toNode objectAt:i] superview];
if ([ toFakeUG isPatchParameter])
{
[[fromFakeUG clavier] connectNoteSenderTo:
[[toFakeUG patchParam] noteReceiver]];
}
else
{
midi = [fromFakeUG midi];
[midi connectNoteSenderTo:
[[toFakeUG patchParam] noteReceiver]];
}
}
isAllocated = YES;
}
if (xmemory)
{
if ([[fromNode superview] isData])
{
pp = [[superview getOrch] allocSynthData:MK_xData
length:[[fromNode superview] getLength]];
isAllocated = YES;
}
else
{
pp = [[superview getOrch] allocPatchpoint:MK_xPatch];
isAllocated = YES;
}
}
else
{
if ([[fromNode superview] isData])
{
if (!([[fromNode superview] isSineROM]))
{
pp = [[superview getOrch] allocSynthData:MK_yData
length:[[fromNode superview] getLength]];
isAllocated = YES;
}
}
else
{
pp = [[superview getOrch] allocPatchpoint:MK_yPatch];
isAllocated = YES;
}
}
if (! pp & ![[fromNode superview] isSineROM])
{
NXRunAlertPanel(getAppName(),
"Is DSP being used by another app? Could not allocate %s",
NULL, NULL, NULL,
[self getName]);
isAllocated = NO;
return nil;
}
if ([[fromNode superview] hasConstant])
{
[pp setToConstant:
DSPDoubleToFix24(atod([[fromNode superview] getConstant]))];
}
return self;
}
-deallocPPMK
{
[pp finish];
[pp dealloc];
pp = nil;
isAllocated = NO;
return self;
}
-makeConnectionsMK
{
int i;
if (!([[fromNode superview] isSineROM]))
{
[[[fromNode superview] getUG]
perform:sel_getUid([[fromNode superview]
getConnectionName:[fromNode getTag]]) with:pp];
for (i=0; i<[toNode count]; i++)
{
id node = [toNode objectAt:i];
[[[node superview] getUG]
perform:sel_getUid([[node superview]
getConnectionName:[node getTag]])
with:pp];
}
}
return self;
}
-eraseSelf
{
NXRect fromFrame, toFrame;
int i;
id fromFakeUG;
double width;
fromFakeUG = [fromNode superview];
#ifdef DEBUG_ERASE
printf("(FakePatchPoint %s -eraseSelf)\n", [self getName], [fromFakeUG getName]);
#endif DEBUG_ERASE
for (i=0; i<[toNode count]; i++)
{
fromFrame = [fromNode frame];
toFrame = [[toNode objectAt:i] frame];
[[fromNode superview] convertRect:&fromFrame toView:self];
[[[toNode objectAt:i] superview] convertRect:&toFrame toView:self];
PSmoveto(fromFrame.origin.x+fromFrame.size.width/2,
fromFrame.origin.y+fromFrame.size.height/2);
PSlineto(toFrame.origin.x+toFrame.size.width/2,
toFrame.origin.y+toFrame.size.height/2);
PSsetgray(NX_LTGRAY);
if ([fromFakeUG isClavier] || [fromFakeUG isMidi])
{
width = 2*LINEWIDTH;
}
else
{
width = LINEWIDTH;
}
PSsetlinewidth(width);
PSstroke();
NXPing();
}
return self;
}
-removeSelf
{
int i;
[self lockFocus];
[self eraseSelf];
[self unlockFocus];
[self closeInspector];
#ifdef DEBUG_ERASE
printf("(FakePatchPoint %s - removeSelf) Attempting to remove connection %d on fromfakeUG: %s\n",
[self getName], [fromNode getTag], [[fromNode superview] getName]);
#endif DEBUG_ERASE
/**** Old Way
[[fromNode superview] remConnection:[fromNode getTag]];
*****************/
[[fromNode superview] nilConnectionsWithId:self];
for (i=0; i<[toNode count]; i++)
{
#ifdef DEBUG_ERASE
printf("(FakePatchPoint %s - removeSelf) Attempting to remove connection %d on fromfakeUG: %s\n",
[self getName],
[[toNode objectAt:i] getTag],
[[[toNode objectAt:i] superview] getName]);
#endif DEBUG_ERASE
/**** Old way
[[[toNode objectAt:i] superview] remConnection:
[[toNode objectAt:i] getTag]];
*****************/
[[[toNode objectAt:i] superview] nilConnectionsWithId:self];
}
#ifdef DEBUG_ERASE
printf("(FakePatchPoint %s - removeSelf) Attempting to remove 0x%x from list in %s\n",
[self getName],
self,
[superview getName]);
#endif DEBUG_ERASE
[superview remFakePatchPointFromList:self];
return self;
}
-drawSelf:(const NXRect *)rects :(int)rectCount
{
int i;
double gray, width;
int x1, y1, x2, y2;
NXRect fromFrame, toFrame;
id fromFakeUG, toFakeUG;
fromFakeUG = [fromNode superview];
for (i=0; i<[toNode count]; i++)
{
toFakeUG = [[toNode objectAt:i] superview];
if ((![fromFakeUG getErasing]) && (![toFakeUG getErasing]))
{
fromFrame = [fromNode frame];
toFrame = [[toNode objectAt:i] frame];
[fromFakeUG convertRect:&fromFrame toView:self];
[toFakeUG convertRect:&toFrame toView:self];
x1 = fromFrame.origin.x+fromFrame.size.width/2;
y1 = fromFrame.origin.y+fromFrame.size.height/2;
x2 = toFrame.origin.x+toFrame.size.width/2;
y2 = toFrame.origin.y+toFrame.size.height/2;
PSmoveto(x1, y1);
PSlineto(x2, y2);
if ([superview getSelected]==self)
{
gray = NX_WHITE;
width = LINEWIDTH;
}
else
{
if ( ([fromFakeUG isClavier] && [toFakeUG isPatchParameter]) ||
([fromFakeUG isMidi] && [toFakeUG isPatchParameter]))
{
gray = 0.25;
width = 2*LINEWIDTH;
}
else
{
if (xmemory)
{
gray = NX_DKGRAY;
width = LINEWIDTH;
}
else
{
gray = NX_BLACK;
width = LINEWIDTH;
}
}
}
PSsetgray(gray);
PSsetlinewidth(width);
PSstroke();
NXPing();
}
}
return self;
}
- write:(NXTypedStream *) stream
{
char *aName;
aName = theName;
[super write:stream];
if (inspector)
{
useInspectorRect = YES;
[inspector getFrame:&inspectorRect];
}
else
{
useInspectorRect = NO;
inspectorRect.origin.x = -1;
inspectorRect.origin.y = -1;
inspectorRect.size.width = -1;
inspectorRect.size.height = -1;
}
NXWriteTypes(stream, "*", &aName);
NXWriteTypes(stream, "@", &fromNode);
NXWriteTypes(stream, "@", &toNode);
NXWriteTypes(stream, "c", &xmemory);
NXWriteTypes(stream, "i", &allocOrder);
NXWriteTypes(stream, "d", &inspectorRect.origin.x);
NXWriteTypes(stream, "d", &inspectorRect.origin.y);
NXWriteTypes(stream, "d", &inspectorRect.size.width);
NXWriteTypes(stream, "d", &inspectorRect.size.height);
NXWriteTypes(stream, "c", &useInspectorRect);
NXWriteTypes(stream, "c", &inspectorDisplayed);
return self;
}
- read:(NXTypedStream *) stream
{
int version;
id aPP;
char *old_name;
isAllocated = NO;
[super read:stream];
allocOrder = 1;
useInspectorRect = NO;
inspectorRectJustLoaded = NO;
version = NXTypedStreamClassVersion(stream, "FakePatchPoint");
switch (version)
{
case(3):
{
NXReadTypes(stream, "*", &old_name);
NXReadTypes(stream, "@", &fromNode);
NXReadTypes(stream, "@", &toNode);
NXReadTypes(stream, "c", &xmemory);
NXReadTypes(stream, "i", &allocOrder);
NXReadTypes(stream, "d", &inspectorRect.origin.x);
NXReadTypes(stream, "d", &inspectorRect.origin.y);
NXReadTypes(stream, "d", &inspectorRect.size.width);
NXReadTypes(stream, "d", &inspectorRect.size.height);
NXReadTypes(stream, "c", &useInspectorRect);
NXReadTypes(stream, "c", &inspectorDisplayed);
inspectorRectJustLoaded = YES;
if (old_name)
{
strcpy(theName, old_name);
}
else
{
strcpy(theName, "");
}
break;
}
case(2):
{
NXReadTypes(stream, "*@@ci",
&old_name, &fromNode, &toNode, &xmemory, &allocOrder);
if (old_name)
{
strcpy(theName, old_name);
}
else
{
strcpy(theName, "");
}
break;
}
default:
{
/* Older versions */
/*ME* Observed malloc error on an initial attempt to load an old file */
NXReadTypes(stream, "*@@c@",
&old_name, &fromNode, &toNode, &xmemory, &aPP);
allocOrder = 1;
if (old_name)
{
strcpy(theName, old_name);
}
else
{
strcpy(theName, "");
}
}
}
return self;
}
- printSelf
{
int i;
printf("\n===============================================\n");
printf("- (FakePatchPoint %s) %d toNodes\n",
[self getName],
(int) [toNode count]);
printf(" > fromNode: goes to tag %d on fakeUG %s\n",
[fromNode getTag],
[[fromNode superview] getName]);
for (i=0; i<[toNode count]; i++)
{
printf(" > toNode %d: goes to tag %d on fakeUG: %s\n",
i,
[[toNode objectAt:i] getTag],
[[[toNode objectAt:i] superview] getName]);
}
return self;
}
- displayIfDoubleClick
{
clickCount++;
if (clickCount >= 2)
{
clickCount = 0;
[self displayInspector];
}
return self;
}
- highlightSelf
{
if ( (![theSP windowMiniaturized]) && doHighlight)
{
[superview setSelected:self];
[window removeFromEventMask:NX_LMOUSEDRAGGEDMASK];
[window flushWindow];
[superview display];
}
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.