File: SCREENLineStipple.c

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (132 lines) | stat: -rw-r--r-- 4,269 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
	SCREENLineStipple.c		
  
	AUTHORS:

		Allen.Ingling@nyu.edu		awi 
  
	PLATFORMS:	
	
		Only OS X for now.
    

	HISTORY:

		03/18/05	awi		Created.  

	TO DO:
  
*/


#include "Screen.h"

// If you change the useString then also change the corresponding synopsis string in ScreenSynopsis.c
static char useString[] = "[stippleEnabled stippleFactor stipleVector]=Screen('LineStipple', windowPtr, [enable], [factor], [stipplePattern] )";                                          
//                                                                                           1           2         3         4      
static char synopsisString[] = 
	"Set 'DrawLine' to draw dashed lines.  Argument \"stippleArray\" is a 16-element logical array specifying the stipple pattern. "
	"Argument \"factor\"  scales the pattern by an integer mutiple.  By default, factor is 1 and stipplePattern is "
	"[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]"; 
	
static char seeAlsoString[] = "FrameRect";	

static void ConvertShortToStippleArray(PsychNativeBooleanType *patternArray, GLushort shortPattern);
static void ConvertStippleArrayToShort(psych_bool *patternArray, GLushort *shortPattern);

PsychError SCREENLineStipple(void)  
{
	
	PsychWindowRecordType			*winRec;
	static GLushort					stipplePatternTemp;
	psych_bool							isFactorThere, isPatternThere, isFlagThere, didChange;
	double							*newFactor;
	psych_bool							*newPatternArray;
	int								numInputVectorElements;
	PsychNativeBooleanType			*oldPatternArray;
	psych_bool							*newEnableFlag;
								
    
	//all sub functions should have these two lines
	PsychPushHelp(useString, synopsisString,seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check for superfluous arguments
	PsychErrorExit(PsychCapNumInputArgs(4));   //The maximum number of inputs
	PsychErrorExit(PsychCapNumOutputArgs(3));  //The maximum number of outputs

	//get the window record from the window record argument and get info from the window record
	PsychAllocInWindowRecordArg(1, kPsychArgRequired, &winRec);
	
	//return existing values
	PsychCopyOutFlagArg(1, kPsychArgOptional, winRec->stippleEnabled);
	PsychCopyOutDoubleArg(2,  kPsychArgOptional, (double)winRec->stippleFactor); 
	PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 16, 0, &oldPatternArray);
	ConvertShortToStippleArray(oldPatternArray, winRec->stipplePattern);
	
	//read in new values
	didChange=FALSE;
	isFlagThere=PsychAllocInFlagArg(2, kPsychArgOptional, &newEnableFlag);
	if(isFlagThere && *newEnableFlag != winRec->stippleEnabled){
		didChange=TRUE;
		winRec->stippleEnabled=*newEnableFlag;
	}
	
	isFactorThere=PsychAllocInDoubleArg(3, kPsychArgOptional, &newFactor);
	if(isFactorThere && (GLint)(*newFactor) != winRec->stippleFactor){
		didChange=TRUE;
		winRec->stippleFactor=(GLint)(*newFactor);
	}
	
	//NOTE: fix PsychAllocInFlagArgVector so that it limits to numInputVectorElements.  
	isPatternThere=PsychAllocInFlagArgVector(4, kPsychArgOptional, &numInputVectorElements, &newPatternArray);
	if(isPatternThere){
		if(numInputVectorElements != 16)
			PsychErrorExitMsg(PsychError_inputMatrixIllegalDimensionSize, "Argument \"stipplePattern\" should be a vector of 16 elements in size");
		ConvertStippleArrayToShort(newPatternArray, &stipplePatternTemp);
		if(stipplePatternTemp != winRec->stipplePattern){
			didChange=TRUE;
			winRec->stipplePattern=stipplePatternTemp;
		}
	}
	
	//Update GL context according to new settings. 
	if(didChange){   //avoids unnecessary context switches
		PsychSetGLContext(winRec);
		glLineStipple(winRec->stippleFactor, winRec->stipplePattern);
		if(winRec->stippleEnabled)
			glEnable(GL_LINE_STIPPLE);
		else
			glDisable(GL_LINE_STIPPLE);
	}
   
 	//All psychfunctions require this.
	return(PsychError_none);
}


static void ConvertShortToStippleArray(PsychNativeBooleanType *patternArray, GLushort shortPattern)
{
	int i;
	
	for(i=0;i<16;i++){
		if(shortPattern & 1)
			patternArray[i]=1;
		else
			patternArray[i]=0;
		shortPattern=shortPattern>>1;
	}
}


static void ConvertStippleArrayToShort(psych_bool *patternArray, GLushort *shortPattern)
{
	int i;
	
	*shortPattern=0;
	for(i=0;i<16;i++){
		*shortPattern=*shortPattern<<1;
		if(patternArray[15-i])
			*shortPattern=*shortPattern | 1;
	}
}