1 %{
2 //////////////////////////////////////////////////////////////////////
3 //
4 // Pixie
5 //
6 // Copyright � 1999 - 2003, Okan Arikan
7 //
8 // Contact: okan@cs.utexas.edu
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 ///////////////////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////////
26 //
27 // File : sl.y
28 // Classes : -
29 // Description : This is the parser file for CShader
30 //
31 ////////////////////////////////////////////////////////////////////////
32 #undef alloca
33 #include <math.h>
34 #include <string.h>
35
36 #include "common/global.h"
37 #include "common/containers.h"
38 #include "shader.h"
39 #include "slcode.h"
40 #include "error.h"
41 #include "renderer.h"
42 #include "dso.h"
43 #include "ri_config.h"
44
45 /////////////////////////////////////////////////////////////////////////////////////
46 // First some temporary data structures used during the script parsing
47
48
49 // Some forward definitions
50 void slerror(const char *); // Forward definition for stupid yacc
51 int sllex(void ); // Forward definition for stupid yacc
52
53 const char *initLabel = "#!Init"; // The label for the init
54 const char *codeLabel = "#!Code"; // The label for the code
55
56 typedef struct TSlVariable {
57 char name[64];
58 int index;
59 int multiplicity;
60 EVariableType type;
61 EVariableClass container;
62 int uniform;
63 CVariable *variable;
64 TSlVariable *next;
65 } TSlVariable;
66
67 typedef struct TSlLabel {
68 char name[64];
69 int index;
70 TArgument *argument;
71 TSlLabel *next;
72 } TSlLabel;
73
74 typedef struct {
75 ESlCode entryPoint;
76 const char *name;
77 int nargs;
78 unsigned int usedParameters;
79 } TSlOpcode;
80
81 typedef struct {
82 ESlCode entryPoint;
83 const char *name;
84 const char *prototype;
85 unsigned int usedParameters;
86 } TSlFunction;
87
88 #define DEFOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post,params) {OPCODE_##name,text,nargs,params},
89 #define DEFSHORTOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post,params) {OPCODE_##name,text,nargs,params},
90 #define DEFLINKOPCODE(name,text,nargs) {OPCODE_##name,text,nargs,0},
91 #define DEFFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)
92 #define DEFLIGHTFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)
93 #define DESHORTFFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)
94 #define DEFLINKFUNC(name,text,prototype,par)
95
96 static TSlOpcode opcodes[] = {
97 #include "scriptOpcodes.h"
98 { OPCODE_NOP , NULL , 0 }
99 };
100
101 #undef DEFOPCODE
102 #undef DEFSHORTOPCODE
103 #undef DEFLINKOPCODE
104 #undef DEFFUNC
105 #undef DEFLIGHTFUNC
106 #undef DEFSHORTFUNC
107 #undef DEFLINKFUNC
108
109 #define DEFOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post)
110 #define DEFSHORTOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post)
111 #define DEFLINKOPCODE(name,text,nargs)
112 #define DEFFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par) {FUNCTION_##name,text,prototype,par},
113 #define DEFLIGHTFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par) {FUNCTION_##name,text,prototype,par},
114 #define DEFSHORTFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par) {FUNCTION_##name,text,prototype,par},
115 #define DEFLINKFUNC(name,text,prototype,par) {FUNCTION_##name,text,prototype,par},
116 static TSlFunction functions[] = {
117 #include "scriptFunctions.h"
118 { OPCODE_NOP , NULL , NULL }
119 };
120
121
122 #undef DEFOPCODE
123 #undef DEFSHORTOPCODE
124 #undef DEFLINKOPCODE
125 #undef DEFFUNC
126 #undef DEFSHORTFUNC
127 #undef DEFLINKFUNC
128
129
130 ////////////////////////////////////////////////////////////////////////////////////////////////////
131 //
132 // This structure holds the compiling context
133 //
134 //
135 typedef struct {
136 const char *name; // Name of the file being parsed
137 int passNumber; // Current pass number (we make 2 passes)
138 int parsingInit; // TRUE if we're parsing the init code
139 int numErrors; // Number of errors encountered during parse
140 int accessorType; // Accessor type for _interpolatable_ parameters
141
142 // Pass 1
143 int numCode; // The number of code blocks
144 int numArgument; // The number of argument blocks
145 int numConstants; // The number of constants
146 int numVariables; // The number of variables (local + parameters)
147 int numStrings; // The number of strings
148
149 int constantSize; // Total size required by the constants
150 int varyingSize; // Total size required by the variables
151
152 int shaderType; // Type of the shader
153
154 int uniform; // TRUE if the current expression is uniform
155 int opcodeUniform; // TRUE if the opcode/function is uniform
156
157 // Pass 2
158 EVariableType currentParameterType; // The type of the current parameter
159 int currentParameterMutable;// TRUE if the current parameter is global or writable
160 EVariableClass currentParameterClass; // The container class of the current parameter
161 int currentConstant;
162 int currentVariable;
163 int currentString;
164
165 int currentConstantSize;
166 int currentVaryingSize;
167
168 float *currentArray; // Array items go here as we read them
169 char **currentStringArray; // If the array is string, we this pointer instead
170 int numArrayItemsRemaining; // Number of array items we're still expecting to read
171
172 char currentOpcode[64]; // Holds the opcode being parsed
173 char currentPrototype[64]; // Holds the prototype being parsed
174 int currentArgument; // The current argument number
175 unsigned int usedParameters; // Used parameters by this shader
176 TCode *currentOpcodePlace; // Points to the code that should holds the opcode
177 TArgument *currentArgumentPlace; // Points to the current argument that should hold the argument
178
179 int codeEntryPoint; // Indices in the code array for corresponding entry points
180 int initEntryPoint;
181
182 char *memory; // The memory base for the area that's allocated
183 TCode *code; // Code blocks
184 TArgument *arguments; // Argument blocks
185 char *constants; // Constants blocks
186 int *varyingSizes; // Holds the size of each varying in codes
187 char **strings; // Strings defined
188 void **constantEntries; // Where the constant entries are stored
189
190 TSlVariable *definedVariables; // List of defined variables
191 TSlLabel *labelReferences; // List of label references
192 TSlLabel *labelDefinitions; // List of label definitions
193 } TShaderData;
194
195 TShaderData currentData;
196
197 ///////////////////////////////////////////////////////////////////////
198 // Function : numComponents
199 // Description : Returns the number of codes that a particular type takes
200 // Return Value : Size in codes
201 // Comments :
numComponents(EVariableType type)202 static int numComponents(EVariableType type) {
203 switch(type) {
204 case TYPE_FLOAT:
205 return 1;
206 break;
207 case TYPE_COLOR:
208 return 3;
209 break;
210 case TYPE_VECTOR:
211 return 3;
212 break;
213 case TYPE_NORMAL:
214 return 3;
215 break;
216 case TYPE_POINT:
217 return 3;
218 break;
219 case TYPE_MATRIX:
220 return 16;
221 break;
222 case TYPE_QUAD:
223 return 4;
224 break;
225 case TYPE_DOUBLE:
226 return 2;
227 break;
228 case TYPE_STRING:
229 return 1;
230 break;
231 case TYPE_INTEGER:
232 return 1;
233 break;
234 default:
235 slerror("Unknown type (bug)");
236 break;
237 }
238
239 return 0;
240 }
241
242
243 ///////////////////////////////////////////////////////////////////////
244 // Function : newVariable
245 // Description : Add a new variable/parameter
246 // Return Value : The default area if available
247 // Comments :
newVariable(char * name,EVariableType type,int numItems,int parameter)248 static void *newVariable(char *name,EVariableType type,int numItems,int parameter) {
249 const int numComp = numComponents(type);
250
251 switch(currentData.passNumber) {
252 case 1:
253 currentData.numVariables++;
254 if (type == TYPE_STRING)
255 currentData.varyingSize += numItems*numComp*sizeof(char*);
256 else
257 currentData.varyingSize += numItems*numComp*sizeof(float);
258 break;
259 case 2:
260 {
261 // Create a new variable
262 TSlVariable *cVariable = new TSlVariable;
263
264 strcpy(cVariable->name,name);
265 cVariable->multiplicity = numItems;
266 cVariable->type = type;
267 cVariable->container = currentData.currentParameterClass;
268 cVariable->uniform = currentData.uniform;
269 cVariable->variable = NULL;
270 cVariable->index = currentData.currentVariable;
271
272 if (type == TYPE_STRING)
273 currentData.varyingSizes[currentData.currentVariable] = numItems*numComp*sizeof(char*);
274 else
275 currentData.varyingSizes[currentData.currentVariable] = numItems*numComp*sizeof(float);
276
277 if (cVariable->uniform) currentData.varyingSizes[currentData.currentVariable] = -currentData.varyingSizes[currentData.currentVariable];
278
279 currentData.currentVariable++;
280 if (type == TYPE_STRING)
281 currentData.currentVaryingSize += numItems*numComp*sizeof(char*);
282 else
283 currentData.currentVaryingSize += numItems*numComp*sizeof(float);
284
285
286 cVariable->next = currentData.definedVariables;
287 currentData.definedVariables = cVariable;
288
289 // Here's the trick part ...
290 // If this is a parameter, allocate a parameter entry and make sure it points to the right location
291 if (parameter) {
292 CVariable *newVariable;
293 CVariable *gVariable;
294
295 newVariable = new CVariable;
296 strcpy(newVariable->name,name);
297 newVariable->type = type;
298 newVariable->container = currentData.currentParameterClass;
299 newVariable->numItems = numItems;
300 newVariable->numFloats = numItems*numComp;
301 newVariable->entry = cVariable->index;
302 newVariable->usageMarker = 0;
303 newVariable->storage = currentData.currentParameterMutable ? STORAGE_MUTABLEPARAMETER : STORAGE_PARAMETER;
304 if (type == TYPE_STRING) newVariable->defaultValue = new char*[numItems*numComp];
305 else newVariable->defaultValue = new float[numItems*numComp];
306 newVariable->accessor = currentData.accessorType;
307 newVariable->next = NULL;
308 cVariable->variable = newVariable;
309
310 // Is this a global variable ?
311 gVariable = CRenderer::retrieveVariable(name);
312 if (gVariable != NULL) {
313 if (gVariable->storage == STORAGE_GLOBAL) {
314 // If the variable is actually defined
315
316 if (newVariable->type == gVariable->type &&
317 newVariable->numItems == gVariable->numItems &&
318 newVariable->numFloats == gVariable->numFloats &&
319 !(cVariable->uniform ^ ((gVariable->container == CONTAINER_UNIFORM) || (gVariable->container == CONTAINER_CONSTANT)))
320 ) {
321
322 // And it matchces the current definition
323
324 newVariable->storage = STORAGE_GLOBAL;
325 currentData.varyingSizes[cVariable->index] = 0; // It takes up no space in the cache
326
327 // Note: the variable index will be re-pointed at the global when init is run
328 }
329 /*else {
330 // This mismatches the predeclared variable. Issue warning, and continue
331 warning(CODE_CONSISTENCY,"Parameter \"%s\" in shader \"%s\" mismatches predeclared variable\n",gVariable->name,currentData.name);
332 }*/
333 }
334 } //If so, then lets ensure we don't delete it by taking a copy
335
336 return newVariable->defaultValue;
337 }
338 }
339 break;
340 default:
341 break;
342 }
343
344 return NULL;
345 }
346
347 ///////////////////////////////////////////////////////////////////////
348 // Function : addStringReference
349 // Description : Add a reference to a string
350 // Return Value : -
351 // Comments :
addStringReference(char ** items,int numItems)352 static void addStringReference(char **items,int numItems) {
353 int i;
354
355 switch(currentData.passNumber) {
356 case 1:
357 currentData.numArgument += 1; // Add one argument
358 currentData.numConstants += 1; // We have one more constant
359 currentData.numStrings += numItems; // Reserve numItems strings
360 currentData.constantSize += numItems*sizeof(char *); // This is the final constant size we consume
361 break;
362 case 2:
363 assert(currentData.currentConstant < 65535);
364
365 char **dest;
366
367 currentData.currentArgumentPlace->numItems = numItems;
368 currentData.currentArgumentPlace->bytesPerItem = sizeof(char *);
369 currentData.currentArgumentPlace->index = (unsigned short) currentData.currentConstant;
370 currentData.currentArgumentPlace->accessor = SL_IMMEDIATE_OPERAND;
371 currentData.currentArgumentPlace->varyingStep = 0;
372 currentData.constantEntries[currentData.currentConstant] = currentData.constants + currentData.currentConstantSize;
373 dest = (char **) currentData.constantEntries[currentData.currentConstant];
374 currentData.currentConstant++;
375 currentData.currentArgumentPlace++;
376 currentData.currentArgument++;
377 currentData.currentConstantSize += numItems*sizeof(char *);
378
379 // Acturally record the strings
380 for (i=0;i<numItems;i++)
381 dest[i] = currentData.strings[currentData.currentString++] = strdup(items[i]);
382
383 break;
384 default:
385 break;
386 }
387 }
388
389
390 ///////////////////////////////////////////////////////////////////////
391 // Function : addFloatReference
392 // Description : Add a reference to a float
393 // Return Value : -
394 // Comments :
addFloatReference(float * items,int numItems)395 static void addFloatReference(float *items,int numItems) {
396 int i;
397 switch(currentData.passNumber) {
398 case 1:
399 currentData.numArgument += 1;
400 currentData.numConstants += 1;
401 currentData.constantSize += numItems*sizeof(float);
402 break;
403 case 2:
404 assert(currentData.currentConstant < 65536);
405
406 float *dest;
407
408 currentData.currentArgumentPlace->numItems = numItems;
409 currentData.currentArgumentPlace->bytesPerItem = sizeof(float);
410 currentData.currentArgumentPlace->index = (unsigned short) currentData.currentConstant;
411 currentData.currentArgumentPlace->accessor = SL_IMMEDIATE_OPERAND;
412 currentData.currentArgumentPlace->varyingStep = 0;
413 currentData.constantEntries[currentData.currentConstant] = currentData.constants + currentData.currentConstantSize;
414 dest = (float *) currentData.constantEntries[currentData.currentConstant];
415 currentData.currentConstant++;
416 currentData.currentArgumentPlace++;
417 currentData.currentArgument++;
418 currentData.currentConstantSize += numItems*sizeof(float);
419
420 for (i=0;i<numItems;i++) dest[i] = items[i];
421
422 break;
423 default:
424 break;
425 }
426 }
427
428 ///////////////////////////////////////////////////////////////////////
429 // Function : addVariableReference
430 // Description : Add a reference to a variable/parameter
431 // Return Value : -
432 // Comments :
addVariableReference(char * name)433 static void addVariableReference(char *name) {
434 CVariable *var;
435 TSlVariable *cVariable;
436
437 switch(currentData.passNumber) {
438 case 1:
439 currentData.numArgument += 1;
440 break;
441 case 2:
442 currentData.currentArgument++;
443
444 // Search the variables
445 for (cVariable=currentData.definedVariables;cVariable!=NULL;cVariable=cVariable->next) {
446 if (strcmp(cVariable->name,name) == 0) {
447
448 // If this is a global parameter, let the next section deal with it
449 if (cVariable->variable) {
450 // in init, we treat the global as a parameter, but in the init phase, it's a local varying
451 if ((cVariable->variable->storage == STORAGE_GLOBAL) && !currentData.parsingInit) continue;
452 }
453
454 assert(cVariable->index < 65536);
455 assert((cVariable->multiplicity*numComponents(cVariable->type)) < 256);
456
457 currentData.currentArgumentPlace->index = (unsigned short) cVariable->index;
458 currentData.currentArgumentPlace->numItems = (char) (cVariable->multiplicity*numComponents(cVariable->type));
459 currentData.currentArgumentPlace->bytesPerItem = (cVariable->type == TYPE_STRING ? sizeof(char *) : sizeof(float));
460 currentData.currentArgumentPlace->accessor = SL_VARYING_OPERAND;
461 currentData.currentArgumentPlace->varyingStep = (cVariable->uniform ? 0 : currentData.currentArgumentPlace->numItems);
462 currentData.currentArgumentPlace++;
463
464 if (cVariable->uniform == FALSE)
465 currentData.opcodeUniform = FALSE;
466
467 return;
468 }
469 }
470
471 var = CRenderer::retrieveVariable(name);
472
473 if (var != NULL) {
474 currentData.usedParameters |= var->usageMarker;
475
476 assert(var->entry < 65536);
477 assert(var->numFloats < 256);
478
479 currentData.currentArgumentPlace->index = (unsigned short) var->entry;
480 currentData.currentArgumentPlace->numItems = (char) var->numFloats;
481 currentData.currentArgumentPlace->bytesPerItem = (var->type == TYPE_STRING ? sizeof(char *) : sizeof(float));
482 currentData.currentArgumentPlace->accessor = SL_GLOBAL_OPERAND;
483
484 if ((var->container != CONTAINER_UNIFORM) || (var->container != CONTAINER_CONSTANT)) {
485 currentData.opcodeUniform = FALSE;
486 currentData.currentArgumentPlace->varyingStep = currentData.currentArgumentPlace->numItems;
487 } else {
488 currentData.currentArgumentPlace->varyingStep = 0;
489 }
490
491 currentData.currentArgumentPlace++;
492 } else {
493 slerror("Unknown variable");
494 }
495
496 break;
497 default:
498 break;
499 }
500 }
501
502 ///////////////////////////////////////////////////////////////////////
503 // Function : setOpcode
504 // Description : Find/Set an opcode/function
505 // Return Value : -
506 // Comments :
setOpcode()507 static void setOpcode() {
508 switch(currentData.passNumber) {
509 case 1:
510 break;
511 case 2:
512 // Is this an opcode or function
513 if (currentData.currentPrototype[0] == '~') {
514 ESlCode opcode;
515 int i;
516
517 for(i=0;opcodes[i].name != NULL;i++) {
518 if (strcmp(opcodes[i].name,currentData.currentOpcode) == 0)
519 if (opcodes[i].nargs == currentData.currentArgument) {
520 opcode = opcodes[i].entryPoint;
521 break;
522 }
523 }
524
525 if (opcodes[i].name == NULL)
526 slerror("Unknown opcode");
527 else {
528 assert((currentData.currentArgument+2) < 256);
529 assert((currentData.opcodeUniform) < 256);
530
531 // Save the opcode
532 currentData.usedParameters |= opcodes[i].usedParameters;
533 currentData.currentOpcodePlace->opcode = (int) opcode;
534 currentData.currentOpcodePlace->numArguments = (unsigned char) (currentData.currentArgument);
535 currentData.currentOpcodePlace->uniform = (unsigned char) (currentData.opcodeUniform);
536 currentData.currentOpcodePlace++;
537 }
538 } else {
539 int i;
540 ESlCode opcode;
541
542 for(i=0;functions[i].name != NULL;i++) {
543 if (strcmp(functions[i].name,currentData.currentOpcode) == 0) {
544 if (strcmp(functions[i].prototype,currentData.currentPrototype) == 0) {
545 currentData.usedParameters |= functions[i].usedParameters;
546 opcode = functions[i].entryPoint;
547 break;
548 } else {
549 // Do a pattern match
550
551
552 // The return types must match exactly
553 if (functions[i].prototype[0] != currentData.currentPrototype[0]) continue;
554
555 {
556 int j,k,t;
557
558 t = FALSE;
559
560 for (j=2,k=2;(currentData.currentPrototype[j] != '\0') && (functions[i].prototype[k] != '\0');j++,k++) {
561 // Do the current parameters match
562 if (currentData.currentPrototype[j] == functions[i].prototype[k]) continue;
563 // Does the function match any parameter ?
564 else if (functions[i].prototype[k] == '.') continue;
565 // Is the current parameter a * or + ?
566 else if ((functions[i].prototype[k] == '+') || (functions[i].prototype[k] == '*')) {
567 k-=2;
568 j--;
569 continue;
570 // Is the current parameter a parameter list ?
571 } else if (functions[i].prototype[k] == '!') {
572 if ((currentData.currentPrototype[j] == 's') || (currentData.currentPrototype[j] == 'S')) {
573 j++;
574 k--;
575 } else {
576 t = TRUE;
577 break;
578 }
579 } else {
580 t = TRUE;
581 break;
582 }
583 }
584
585
586 if (t == FALSE) {
587 if (
588 ((functions[i].prototype[k] == '\0') && (currentData.currentPrototype[j] == '\0')) ||
589 ((functions[i].prototype[k] == '+') || (functions[i].prototype[k] == '*')) ||
590 (functions[i].prototype[k] == '!') ||
591 (functions[i].prototype[k+1] == '*')) {
592 // We found our function/opcode
593 currentData.usedParameters |= functions[i].usedParameters;
594 opcode = functions[i].entryPoint;
595 break;
596 } else {
597 continue;
598 }
599 }
600 }
601 }
602 }
603 }
604
605 // Save the opcode
606 if (functions[i].name != NULL) {
607 assert((currentData.currentArgument+2) < 256);
608 assert(currentData.opcodeUniform < 256);
609
610 currentData.currentOpcodePlace->opcode = (int) opcode;
611 currentData.currentOpcodePlace->numArguments = (unsigned char) (currentData.currentArgument);
612 currentData.currentOpcodePlace->uniform = (unsigned char) (currentData.opcodeUniform);
613 currentData.currentOpcodePlace++;
614 } else {
615 // Allright, we could not find the function, check the DSO shaders
616 CDSO *dso;
617
618 // See if this is a DSO function
619 if ((dso = CRenderer::getDSO(currentData.currentOpcode,currentData.currentPrototype)) != NULL) {
620
621 // We have the DSO
622 if (currentData.currentPrototype[0] == 'o') currentData.currentOpcodePlace->opcode = FUNCTION_DSO_VOID;
623 else currentData.currentOpcodePlace->opcode = FUNCTION_DSO;
624
625 currentData.currentOpcodePlace->numArguments = (unsigned char) (currentData.currentArgument);
626 currentData.currentOpcodePlace->uniform = (unsigned char) (currentData.opcodeUniform);
627 currentData.currentOpcodePlace->dso = dso;
628 currentData.currentOpcodePlace++;
629 } else {
630 slerror("Unknown function");
631 }
632 }
633 }
634 break;
635 default:
636 break;
637 }
638 }
639
640
641 ///////////////////////////////////////////////////////////////////////
642 // Function : newLabel
643 // Description : Create a new label definition/reference
644 // Return Value : -
645 // Comments :
newLabel(const char * name,int reference)646 static void newLabel(const char *name,int reference) {
647 switch(currentData.passNumber) {
648 case 1:
649 if (reference)
650 currentData.numArgument++;
651 break;
652 case 2:
653 {
654 TSlLabel *cLabel = new TSlLabel;
655
656 strcpy(cLabel->name,name);
657 cLabel->index = (int) (currentData.currentOpcodePlace - currentData.code);
658
659 if (reference) {
660 cLabel->next = currentData.labelReferences;
661 currentData.labelReferences = cLabel;
662 cLabel->argument = currentData.currentArgumentPlace++;
663 currentData.currentArgument++;
664 } else {
665 TSlLabel *tLabel;
666
667 for (tLabel=currentData.labelDefinitions;tLabel!=NULL;tLabel=tLabel->next) {
668 if (strcmp(tLabel->name,cLabel->name) == 0) {
669 slerror("Duplicate label definition\n");
670 }
671 }
672
673 cLabel->argument = NULL;
674 cLabel->next = currentData.labelDefinitions;
675 currentData.labelDefinitions = cLabel;
676 }
677 }
678 break;
679 default:
680 break;
681 }
682 }
683
684 // Some forward references
685 void reset();
686 void alloc();
687 CShader *shaderCreate(const char *);
688 int getVariable(char *);
689 int getOpcode(char *,int);
690 int getFunction(char *,char *,int *ps = NULL);
691 void *newVariable(char *,int,int,int,int m=1);
692 TSlLabel *newLabelDef(char *,int);
693 TSlLabel *newLabelRef(char *,int);
694 %}
695 %union slval {
696 float real;
697 char *string;
698 matrix m;
699 vector v;
700 }
701
702 // Some tokens
703 %token SCRL_PARAMETERS
704 %token SCRL_VARIABLES
705 %token SCRL_OUTPUT
706 %token SCRL_VARYING
707 %token SCRL_UNIFORM
708 %token SCRL_FLOAT
709 %token SCRL_COLOR
710 %token SCRL_VECTOR
711 %token SCRL_NORMAL
712 %token SCRL_POINT
713 %token SCRL_MATRIX
714 %token SCRL_STRING
715
716 %token SCRL_SURFACE
717 %token SCRL_DISPLACEMENT
718 %token SCRL_IMAGER
719 %token SCRL_LIGHTSOURCE
720 %token SCRL_VOLUME
721 %token SCRL_GENERIC
722
723 %token SCRL_DSO
724
725 %token SCRL_INIT
726 %token SCRL_CODE
727
728 %token SCRL_DOT
729 %token SCRL_COLON
730 %token SCRL_EQUAL
731 %token SCRL_OPEN_PARANTHESIS
732 %token SCRL_CLOSE_PARANTHESIS
733 %token SCRL_OPEN_SQR_PARANTHESIS
734 %token SCRL_CLOSE_SQR_PARANTHESIS
735 %token SCRL_COMMA
736 %token SCRL_NL
737
738 %token<string> SCRL_TEXT_VALUE
739 %token<string> SCRL_IDENTIFIER_VALUE
740 %token<string> SCRL_LABEL_VALUE
741 %token<real> SCRL_FLOAT_VALUE
742 %type<v> slVectorIn
743 %type<v> slVector
744 %type<v> slVectorValue
745 %%
746 start:
747 slType
748 slParameterDefinitions
749 slVariableDefinitions
750 slInit
751 slCode
752 slEmptySpace
753 ;
754
755 slEmptySpace:
756 |
757 SCRL_NL
758 slEmptySpace
759 ;
760
761 slVectorIn: SCRL_EQUAL
762 SCRL_TEXT_VALUE
763 SCRL_FLOAT_VALUE
764 {
765 $$[0] = $3;
766 $$[1] = $3;
767 $$[2] = $3;
768 }
769 |
770 SCRL_EQUAL
771 SCRL_TEXT_VALUE
772 SCRL_OPEN_SQR_PARANTHESIS
773 SCRL_FLOAT_VALUE
774 SCRL_FLOAT_VALUE
775 SCRL_FLOAT_VALUE
776 SCRL_CLOSE_SQR_PARANTHESIS
777 {
778 $$[0] = $4;
779 $$[1] = $5;
780 $$[2] = $6;
781 }
782 |
783 SCRL_EQUAL
784 SCRL_FLOAT_VALUE
785 {
786 $$[0] = $2;
787 $$[1] = $2;
788 $$[2] = $2;
789 }
790 |
791 SCRL_EQUAL
792 SCRL_OPEN_SQR_PARANTHESIS
793 SCRL_FLOAT_VALUE
794 SCRL_FLOAT_VALUE
795 SCRL_FLOAT_VALUE
796 SCRL_CLOSE_SQR_PARANTHESIS
797 {
798 $$[0] = $3;
799 $$[1] = $4;
800 $$[2] = $5;
801 }
802 |
803 {
804 $$[0] = 0;
805 $$[1] = 0;
806 $$[2] = 0;
807 }
808 ;
809
810 slVector: slVectorIn
811 {
812 $$[0] = $1[0];
813 $$[1] = $1[1];
814 $$[2] = $1[2];
815 }
816 ;
817
818 slType:
819 SCRL_SURFACE
820 SCRL_NL
821 {
822 currentData.shaderType = SL_SURFACE;
823 currentData.accessorType = ACCESSOR_SURFACE;
824 }
825 |
826 SCRL_DISPLACEMENT
827 SCRL_NL
828 {
829 currentData.shaderType = SL_DISPLACEMENT;
830 currentData.accessorType = ACCESSOR_DISPLACEMENT;
831 }
832 |
833 SCRL_LIGHTSOURCE
834 SCRL_NL
835 {
836 currentData.shaderType = SL_LIGHTSOURCE;
837 // Note: we don't set accessorType because you can't interpolate into
838 // light shader parameters
839 }
840 |
841 SCRL_VOLUME
842 SCRL_NL
843 {
844 currentData.shaderType = SL_ATMOSPHERE;
845 currentData.accessorType = ACCESSOR_ATMOSPHERE;
846 // Note: we can assume the accessor is atmosphere as that's the only
847 // volume shader that can be interpolated into
848 }
849 |
850 SCRL_IMAGER
851 SCRL_NL
852 {
853 currentData.shaderType = SL_IMAGER;
854 }
855 ;
856
857 slParameterDefinitions:
858 SCRL_PARAMETERS
859 SCRL_COLON
860 SCRL_NL
861 slParameters
862 ;
863
864 slParameters:
865 slParameters
866 slParameter
867 SCRL_NL
868 |
869 ;
870
871 slContainer:
872 SCRL_UNIFORM
873 {
874 currentData.currentParameterClass = CONTAINER_UNIFORM;
875 currentData.currentParameterMutable = FALSE;
876 currentData.uniform = TRUE;
877 }
878 |
879 SCRL_VARYING
880 {
881 currentData.currentParameterClass = CONTAINER_VARYING;
882 currentData.currentParameterMutable = FALSE;
883 currentData.uniform = FALSE;
884 }
885 |
886 SCRL_OUTPUT
887 SCRL_UNIFORM
888 {
889 currentData.currentParameterClass = CONTAINER_UNIFORM;
890 currentData.currentParameterMutable = TRUE;
891 currentData.uniform = TRUE;
892 }
893 |
894 SCRL_OUTPUT
895 SCRL_VARYING
896 {
897 currentData.currentParameterClass = CONTAINER_VARYING;
898 currentData.currentParameterMutable = TRUE;
899 currentData.uniform = FALSE;
900 }
901 |
902 SCRL_OUTPUT
903 {
904 currentData.currentParameterClass = CONTAINER_UNIFORM;
905 currentData.currentParameterMutable = TRUE;
906 currentData.uniform = TRUE;
907 }
908 |
909 {
910 currentData.currentParameterClass = CONTAINER_UNIFORM;
911 currentData.currentParameterMutable = FALSE;
912 currentData.uniform = TRUE;
913 }
914 ;
915
916
917 slParameter:
918 slContainer
919 slAParameter
920 ;
921
922
923 slAParameter:
924 slFloatParameter
925 |
926 slStringParameter
927 |
928 slColorParameter
929 |
930 slVectorParameter
931 |
932 slNormalParameter
933 |
934 slPointParameter
935 |
936 slMatrixParameter
937 ;
938
939
940 slFloatParameter:
941 SCRL_FLOAT
942 SCRL_IDENTIFIER_VALUE
943 SCRL_EQUAL
944 SCRL_FLOAT_VALUE
945 {
946 float *def = (float *) newVariable($2,TYPE_FLOAT,1,TRUE);
947
948 if (def != NULL) {
949 def[0] = $4;
950 }
951 }
952 |
953 SCRL_FLOAT
954 SCRL_IDENTIFIER_VALUE
955 {
956 float *def = (float *) newVariable($2,TYPE_FLOAT,1,TRUE);
957
958 if (def != NULL) {
959 def[0] = 0;
960 }
961 }
962 |
963 SCRL_FLOAT
964 SCRL_IDENTIFIER_VALUE
965 SCRL_OPEN_SQR_PARANTHESIS
966 SCRL_FLOAT_VALUE
967 SCRL_CLOSE_SQR_PARANTHESIS
968 SCRL_EQUAL
969 {
970 float *def = (float *) newVariable($2,TYPE_FLOAT,(int) $4,TRUE);
971
972 if (def != NULL) {
973 int i;
974
975 for (i=0;i<(int) $4;i++)
976 def[i] = 0;
977
978 currentData.currentArray = def;
979 }
980
981 currentData.numArrayItemsRemaining = (int) $4;
982 }
983 slFloatArrayInitializer
984 |
985 SCRL_FLOAT
986 SCRL_IDENTIFIER_VALUE
987 SCRL_OPEN_SQR_PARANTHESIS
988 SCRL_FLOAT_VALUE
989 SCRL_CLOSE_SQR_PARANTHESIS
990 {
991 float *def = (float *) newVariable($2,TYPE_FLOAT,(int) $4,TRUE);
992
993 if (def != NULL) {
994 int i;
995
996 for (i=0;i<(int) $4;i++)
997 def[i] = 0;
998 }
999 }
1000 ;
1001
1002
1003 slFloatArrayInitializer:
1004 SCRL_OPEN_SQR_PARANTHESIS
1005 slFloatArrayInitializerItems
1006 SCRL_CLOSE_SQR_PARANTHESIS
1007 {
1008 if(currentData.numArrayItemsRemaining){
1009 slerror("Wrong number of items in array initializer\n");
1010 }
1011 }
1012 ;
1013
1014 slFloatArrayInitializerItems:
1015 slFloatArrayInitializerItems
1016 SCRL_FLOAT_VALUE
1017 {
1018 if(currentData.numArrayItemsRemaining > 0){
1019 if(currentData.currentArray){
1020 *currentData.currentArray++ = $2;
1021 }
1022 currentData.numArrayItemsRemaining--;
1023 } else{
1024 slerror("Wrong number of items in array initializer\n");
1025 }
1026 }
1027 |
1028 ;
1029
1030
1031 slStringParameter:
1032 SCRL_STRING
1033 SCRL_IDENTIFIER_VALUE
1034 {
1035 char **def = (char **) newVariable($2,TYPE_STRING,1,TRUE);
1036
1037 switch(currentData.passNumber) {
1038 case 1:
1039 currentData.numStrings++;
1040 break;
1041 case 2:
1042 if (def != NULL) {
1043 *def = currentData.strings[currentData.currentString++] = strdup("*");
1044 }
1045 break;
1046 default:
1047 break;
1048 }
1049 }
1050 |
1051 SCRL_STRING
1052 SCRL_IDENTIFIER_VALUE
1053 SCRL_EQUAL
1054 SCRL_TEXT_VALUE
1055 {
1056 char **def = (char **) newVariable($2,TYPE_STRING,1,TRUE);
1057
1058 switch(currentData.passNumber) {
1059 case 1:
1060 currentData.numStrings++;
1061 break;
1062 case 2:
1063 if (def != NULL) {
1064 *def = currentData.strings[currentData.currentString++] = strdup($4);
1065 }
1066 break;
1067 default:
1068 break;
1069 }
1070 }
1071 |
1072 SCRL_STRING
1073 SCRL_IDENTIFIER_VALUE
1074 SCRL_OPEN_SQR_PARANTHESIS
1075 SCRL_FLOAT_VALUE
1076 SCRL_CLOSE_SQR_PARANTHESIS
1077 SCRL_EQUAL
1078 {
1079 char **def = (char **) newVariable($2,TYPE_STRING,(int) $4,TRUE);
1080
1081 switch(currentData.passNumber) {
1082 case 1:
1083 currentData.numStrings += (int) $4;
1084 break;
1085 case 2:
1086 if (def != NULL) {
1087 int i;
1088
1089 for (i=0;i<(int) $4;i++)
1090 def[i] = NULL;
1091
1092 currentData.currentStringArray = def;
1093 }
1094 break;
1095 default:
1096 break;
1097 }
1098
1099 currentData.numArrayItemsRemaining = (int) $4;
1100 }
1101 slStringArrayInitializer
1102 |
1103 SCRL_STRING
1104 SCRL_IDENTIFIER_VALUE
1105 SCRL_OPEN_SQR_PARANTHESIS
1106 SCRL_FLOAT_VALUE
1107 SCRL_CLOSE_SQR_PARANTHESIS
1108 {
1109 char **def = (char **) newVariable($2,TYPE_STRING,(int) $4,TRUE);
1110
1111 if (def != NULL) {
1112 int i;
1113
1114 for (i=0;i<(int) $4;i++)
1115 def[i] = NULL;
1116 }
1117 }
1118
1119 slStringArrayInitializer:
1120 SCRL_OPEN_SQR_PARANTHESIS
1121 slStringArrayInitializerItems
1122 SCRL_CLOSE_SQR_PARANTHESIS
1123 {
1124 if(currentData.numArrayItemsRemaining){
1125 slerror("Wrong number of items in array initializer\n");
1126 }
1127 }
1128 ;
1129
1130 slStringArrayInitializerItems:
1131 slStringArrayInitializerItems
1132 SCRL_TEXT_VALUE
1133 {
1134 if(currentData.numArrayItemsRemaining > 0){
1135 if(currentData.currentArray){
1136 *currentData.currentStringArray++ = currentData.strings[currentData.currentString++] = strdup($2);
1137 }
1138 currentData.numArrayItemsRemaining--;
1139 }
1140 else{
1141 slerror("Wrong number of items in array initializer\n");
1142 }
1143 }
1144 |
1145 ;
1146
1147
1148 slColorParameter:
1149 SCRL_COLOR
1150 SCRL_IDENTIFIER_VALUE
1151 {
1152 currentData.currentParameterType = TYPE_COLOR;
1153 }
1154 slVector
1155 {
1156 float *def = (float *) newVariable($2,currentData.currentParameterType,1,TRUE);
1157
1158 if (def != NULL) {
1159 movvv(def,$4);
1160 }
1161 }
1162 |
1163 SCRL_COLOR
1164 SCRL_IDENTIFIER_VALUE
1165 SCRL_OPEN_SQR_PARANTHESIS
1166 SCRL_FLOAT_VALUE
1167 SCRL_CLOSE_SQR_PARANTHESIS
1168 SCRL_EQUAL
1169 {
1170 float *def = (float *) newVariable($2,TYPE_COLOR,(int) $4,TRUE);
1171
1172 if(def != NULL)
1173 currentData.currentArray = def;
1174 currentData.numArrayItemsRemaining = (int) $4;
1175 }
1176 slVectorArrayInitializer
1177 |
1178 SCRL_COLOR
1179 SCRL_IDENTIFIER_VALUE
1180 SCRL_OPEN_SQR_PARANTHESIS
1181 SCRL_FLOAT_VALUE
1182 SCRL_CLOSE_SQR_PARANTHESIS
1183 {
1184 float *def = (float *) newVariable($2,TYPE_COLOR,(int) $4,TRUE);
1185 }
1186 ;
1187
1188 slVectorParameter:
1189 SCRL_VECTOR
1190 SCRL_IDENTIFIER_VALUE
1191 {
1192 currentData.currentParameterType = TYPE_VECTOR;
1193 }
1194 slVector
1195 {
1196 float *def = (float *) newVariable($2,currentData.currentParameterType,1,TRUE);
1197
1198 if (def != NULL) {
1199 movvv(def,$4);
1200 }
1201 }
1202 |
1203 SCRL_VECTOR
1204 SCRL_IDENTIFIER_VALUE
1205 SCRL_OPEN_SQR_PARANTHESIS
1206 SCRL_FLOAT_VALUE
1207 SCRL_CLOSE_SQR_PARANTHESIS
1208 SCRL_EQUAL
1209 {
1210 float *def = (float *) newVariable($2,TYPE_VECTOR,(int) $4,TRUE);
1211
1212 if(def != NULL) {
1213 currentData.currentArray = def;
1214 }
1215
1216 currentData.numArrayItemsRemaining = (int) $4;
1217 }
1218 slVectorArrayInitializer
1219 |
1220 SCRL_VECTOR
1221 SCRL_IDENTIFIER_VALUE
1222 SCRL_OPEN_SQR_PARANTHESIS
1223 SCRL_FLOAT_VALUE
1224 SCRL_CLOSE_SQR_PARANTHESIS
1225 {
1226 float *def = (float *) newVariable($2,TYPE_VECTOR,(int) $4,TRUE);
1227 }
1228 ;
1229
1230 slNormalParameter:
1231 SCRL_NORMAL
1232 SCRL_IDENTIFIER_VALUE
1233 {
1234 currentData.currentParameterType = TYPE_NORMAL;
1235 }
1236 slVector
1237 {
1238 float *def = (float *) newVariable($2,currentData.currentParameterType,1,TRUE);
1239
1240 if (def != NULL) {
1241 movvv(def,$4);
1242 }
1243 }
1244 |
1245 SCRL_NORMAL
1246 SCRL_IDENTIFIER_VALUE
1247 SCRL_OPEN_SQR_PARANTHESIS
1248 SCRL_FLOAT_VALUE
1249 SCRL_CLOSE_SQR_PARANTHESIS
1250 SCRL_EQUAL
1251 {
1252 float *def = (float *) newVariable($2,TYPE_NORMAL,(int) $4,TRUE);
1253
1254 if(def != NULL) {
1255 currentData.currentArray = def;
1256 }
1257
1258 currentData.numArrayItemsRemaining = (int) $4;
1259 }
1260 slVectorArrayInitializer
1261 |
1262 SCRL_NORMAL
1263 SCRL_IDENTIFIER_VALUE
1264 SCRL_OPEN_SQR_PARANTHESIS
1265 SCRL_FLOAT_VALUE
1266 SCRL_CLOSE_SQR_PARANTHESIS
1267 {
1268 float *def = (float *) newVariable($2,TYPE_NORMAL,(int) $4,TRUE);
1269 }
1270 ;
1271
1272 slPointParameter:
1273 SCRL_POINT
1274 SCRL_IDENTIFIER_VALUE
1275 {
1276 currentData.currentParameterType = TYPE_POINT;
1277 }
1278 slVector
1279 {
1280 float *def = (float *)newVariable($2,currentData.currentParameterType,1,TRUE);
1281
1282 if (def != NULL) {
1283 movvv(def,$4);
1284 }
1285 }
1286 |
1287 SCRL_POINT
1288 SCRL_IDENTIFIER_VALUE
1289 SCRL_OPEN_SQR_PARANTHESIS
1290 SCRL_FLOAT_VALUE
1291 SCRL_CLOSE_SQR_PARANTHESIS
1292 SCRL_EQUAL
1293 {
1294 float *def = (float *) newVariable($2,TYPE_POINT,(int) $4,TRUE);
1295
1296 if(def != NULL) {
1297 currentData.currentArray = def;
1298 }
1299
1300 currentData.numArrayItemsRemaining = (int) $4;
1301 }
1302 slVectorArrayInitializer
1303 |
1304 SCRL_POINT
1305 SCRL_IDENTIFIER_VALUE
1306 SCRL_OPEN_SQR_PARANTHESIS
1307 SCRL_FLOAT_VALUE
1308 SCRL_CLOSE_SQR_PARANTHESIS
1309 {
1310 float *def = (float *) newVariable($2,TYPE_POINT,(int) $4,TRUE);
1311 }
1312 ;
1313
1314 slVectorValue: SCRL_TEXT_VALUE
1315 SCRL_FLOAT_VALUE
1316 {
1317 $$[0] = $2;
1318 $$[1] = $2;
1319 $$[2] = $2;
1320 }
1321 |
1322 SCRL_TEXT_VALUE
1323 SCRL_OPEN_SQR_PARANTHESIS
1324 SCRL_FLOAT_VALUE
1325 SCRL_FLOAT_VALUE
1326 SCRL_FLOAT_VALUE
1327 SCRL_CLOSE_SQR_PARANTHESIS
1328 {
1329 $$[0] = $3;
1330 $$[1] = $4;
1331 $$[2] = $5;
1332 }
1333 |
1334 SCRL_FLOAT_VALUE
1335 {
1336 $$[0] = $1;
1337 $$[1] = $1;
1338 $$[2] = $1;
1339 }
1340 |
1341 SCRL_OPEN_SQR_PARANTHESIS
1342 SCRL_FLOAT_VALUE
1343 SCRL_FLOAT_VALUE
1344 SCRL_FLOAT_VALUE
1345 SCRL_CLOSE_SQR_PARANTHESIS
1346 {
1347 $$[0] = $2;
1348 $$[1] = $3;
1349 $$[2] = $4;
1350 }
1351 ;
1352
1353
1354 slVectorArrayInitializer:
1355 SCRL_OPEN_SQR_PARANTHESIS
1356 slVectorArrayInitializerItems
1357 SCRL_CLOSE_SQR_PARANTHESIS
1358 {
1359 if(currentData.numArrayItemsRemaining){
1360 slerror("Wrong number of items in array initializer\n");
1361 }
1362 }
1363 ;
1364
1365 slVectorArrayInitializerItems:
1366 slVectorArrayInitializerItems
1367 slVectorValue
1368 {
1369
1370 if(currentData.numArrayItemsRemaining > 0){
1371 if(currentData.currentArray){
1372 movvv(currentData.currentArray,$2);
1373 currentData.currentArray += 3;
1374 }
1375 currentData.numArrayItemsRemaining--;
1376 } else{
1377 slerror("Wrong number of items in array initializer\n");
1378 }
1379 }
1380 |
1381 ;
1382
1383
1384 slMatrixParameter:
1385 SCRL_MATRIX
1386 SCRL_IDENTIFIER_VALUE
1387 SCRL_EQUAL
1388 SCRL_OPEN_SQR_PARANTHESIS
1389 SCRL_FLOAT_VALUE
1390 SCRL_FLOAT_VALUE
1391 SCRL_FLOAT_VALUE
1392 SCRL_FLOAT_VALUE
1393 SCRL_FLOAT_VALUE
1394 SCRL_FLOAT_VALUE
1395 SCRL_FLOAT_VALUE
1396 SCRL_FLOAT_VALUE
1397 SCRL_FLOAT_VALUE
1398 SCRL_FLOAT_VALUE
1399 SCRL_FLOAT_VALUE
1400 SCRL_FLOAT_VALUE
1401 SCRL_FLOAT_VALUE
1402 SCRL_FLOAT_VALUE
1403 SCRL_FLOAT_VALUE
1404 SCRL_FLOAT_VALUE
1405 SCRL_CLOSE_SQR_PARANTHESIS
1406 {
1407 float *def = (float *) newVariable($2,TYPE_MATRIX,1,TRUE);
1408
1409 if (def != NULL) {
1410 def[0] = $5;
1411 def[1] = $6;
1412 def[2] = $7;
1413 def[3] = $8;
1414 def[4] = $9;
1415 def[5] = $10;
1416 def[6] = $11;
1417 def[7] = $12;
1418 def[8] = $13;
1419 def[9] = $14;
1420 def[10] = $15;
1421 def[11] = $16;
1422 def[12] = $17;
1423 def[13] = $18;
1424 def[14] = $19;
1425 def[15] = $20;
1426 }
1427 }
1428 |
1429 SCRL_MATRIX
1430 SCRL_IDENTIFIER_VALUE
1431 SCRL_EQUAL
1432 SCRL_FLOAT_VALUE
1433 {
1434 float *def = (float *) newVariable($2,TYPE_MATRIX,1,TRUE);
1435
1436 if (def != NULL) {
1437 def[0] = $4;
1438 def[1] = 0;
1439 def[2] = 0;
1440 def[3] = 0;
1441 def[4] = 0;
1442 def[5] = $4;
1443 def[6] = 0;
1444 def[7] = 0;
1445 def[8] = 0;
1446 def[9] = 0;
1447 def[10] = $4;
1448 def[11] = 0;
1449 def[12] = 0;
1450 def[13] = 0;
1451 def[14] = 0;
1452 def[15] = 1;
1453 }
1454 }
1455 |
1456 SCRL_MATRIX
1457 SCRL_IDENTIFIER_VALUE
1458 {
1459 float *def = (float *) newVariable($2,TYPE_MATRIX,1,TRUE);
1460
1461 if (def != NULL) {
1462 def[0] = 1;
1463 def[1] = 0;
1464 def[2] = 0;
1465 def[3] = 0;
1466 def[4] = 0;
1467 def[5] = 1;
1468 def[6] = 0;
1469 def[7] = 0;
1470 def[8] = 0;
1471 def[9] = 0;
1472 def[10] = 1;
1473 def[11] = 0;
1474 def[12] = 0;
1475 def[13] = 0;
1476 def[14] = 0;
1477 def[15] = 1;
1478 }
1479 }
1480 |
1481 SCRL_MATRIX
1482 SCRL_IDENTIFIER_VALUE
1483 SCRL_OPEN_SQR_PARANTHESIS
1484 SCRL_FLOAT_VALUE
1485 SCRL_CLOSE_SQR_PARANTHESIS
1486 SCRL_EQUAL
1487 {
1488 float *def = (float *) newVariable($2,TYPE_MATRIX,(int) $4,TRUE);
1489
1490 if (def != NULL) {
1491 int i;
1492
1493 for (i=0;i<((int) $4)*16;i++)
1494 def[i] = 0;
1495
1496 currentData.currentArray = def;
1497 }
1498
1499 currentData.numArrayItemsRemaining = (int) $4;
1500 }
1501 slMatrixArrayInitializer
1502 |
1503 SCRL_MATRIX
1504 SCRL_IDENTIFIER_VALUE
1505 SCRL_OPEN_SQR_PARANTHESIS
1506 SCRL_FLOAT_VALUE
1507 SCRL_CLOSE_SQR_PARANTHESIS
1508 {
1509 float *def = (float *) newVariable($2,TYPE_MATRIX,(int) $4,TRUE);
1510
1511 if (def != NULL) {
1512 int i;
1513
1514 for (i=0;i<((int) $4)*16;i++)
1515 def[i] = 0;
1516 }
1517 }
1518 ;
1519
1520
1521 slMatrixArrayInitializer:
1522 SCRL_OPEN_SQR_PARANTHESIS
1523 slMatrixArrayInitializerItems
1524 SCRL_CLOSE_SQR_PARANTHESIS
1525 {
1526 if(currentData.numArrayItemsRemaining){
1527 slerror("Wrong number of items in array initializer\n");
1528 }
1529 }
1530 ;
1531
1532 slMatrixArrayInitializerItems:
1533 slMatrixArrayInitializerItems
1534 SCRL_OPEN_SQR_PARANTHESIS
1535 SCRL_FLOAT_VALUE
1536 SCRL_FLOAT_VALUE
1537 SCRL_FLOAT_VALUE
1538 SCRL_FLOAT_VALUE
1539 SCRL_FLOAT_VALUE
1540 SCRL_FLOAT_VALUE
1541 SCRL_FLOAT_VALUE
1542 SCRL_FLOAT_VALUE
1543 SCRL_FLOAT_VALUE
1544 SCRL_FLOAT_VALUE
1545 SCRL_FLOAT_VALUE
1546 SCRL_FLOAT_VALUE
1547 SCRL_FLOAT_VALUE
1548 SCRL_FLOAT_VALUE
1549 SCRL_FLOAT_VALUE
1550 SCRL_FLOAT_VALUE
1551 SCRL_CLOSE_SQR_PARANTHESIS
1552 {
1553 if(currentData.numArrayItemsRemaining > 0){
1554 if(currentData.currentArray){
1555 currentData.currentArray[0] = $3;
1556 currentData.currentArray[1] = $4;
1557 currentData.currentArray[2] = $5;
1558 currentData.currentArray[3] = $6;
1559 currentData.currentArray[4] = $7;
1560 currentData.currentArray[5] = $8;
1561 currentData.currentArray[6] = $9;
1562 currentData.currentArray[7] = $10;
1563 currentData.currentArray[8] = $11;
1564 currentData.currentArray[9] = $12;
1565 currentData.currentArray[10] = $13;
1566 currentData.currentArray[11] = $14;
1567 currentData.currentArray[12] = $15;
1568 currentData.currentArray[13] = $16;
1569 currentData.currentArray[14] = $17;
1570 currentData.currentArray[15] = $18;
1571
1572 currentData.currentArray += 16;
1573 }
1574 currentData.numArrayItemsRemaining--;
1575 }
1576 else{
1577 slerror("Wrong number of items in array initializer\n");
1578 }
1579 }
1580 |
1581 slMatrixArrayInitializerItems
1582 SCRL_FLOAT_VALUE
1583 {
1584 if(currentData.numArrayItemsRemaining > 0){
1585 if(currentData.currentArray){
1586 currentData.currentArray[0] = $2;
1587 currentData.currentArray[1] = 0;
1588 currentData.currentArray[2] = 0;
1589 currentData.currentArray[3] = 0;
1590 currentData.currentArray[4] = 0;
1591 currentData.currentArray[5] = $2;
1592 currentData.currentArray[6] = 0;
1593 currentData.currentArray[7] = 0;
1594 currentData.currentArray[8] = 0;
1595 currentData.currentArray[9] = 0;
1596 currentData.currentArray[10] = $2;
1597 currentData.currentArray[11] = 0;
1598 currentData.currentArray[12] = 0;
1599 currentData.currentArray[13] = 0;
1600 currentData.currentArray[14] = 0;
1601 currentData.currentArray[15] = 1;
1602
1603 currentData.currentArray += 16;
1604 }
1605 currentData.numArrayItemsRemaining--;
1606 }
1607 else{
1608 slerror("Wrong number of items in array initializer\n");
1609 }
1610 }
1611 |
1612 ;
1613
1614
1615 slVariableDefinitions:
1616 SCRL_VARIABLES
1617 SCRL_COLON
1618 SCRL_NL
1619 slVariables
1620 ;
1621
1622 slVariables:
1623 slVariables
1624 slVariable
1625 SCRL_NL
1626 |
1627 ;
1628
1629 slVariable:
1630 slContainer
1631 slFloatVariable
1632 |
1633 slContainer
1634 slStringVariable
1635 |
1636 slContainer
1637 slColorVariable
1638 |
1639 slContainer
1640 slVectorVariable
1641 |
1642 slContainer
1643 slNormalVariable
1644 |
1645 slContainer
1646 slPointVariable
1647 |
1648 slContainer
1649 slMatrixVariable
1650 ;
1651
1652
1653 slFloatVariable:
1654 SCRL_FLOAT
1655 SCRL_IDENTIFIER_VALUE
1656 {
1657 newVariable($2,TYPE_FLOAT,1,FALSE);
1658 }
1659 |
1660 SCRL_FLOAT
1661 SCRL_IDENTIFIER_VALUE
1662 SCRL_OPEN_SQR_PARANTHESIS
1663 SCRL_FLOAT_VALUE
1664 SCRL_CLOSE_SQR_PARANTHESIS
1665 {
1666 newVariable($2,TYPE_FLOAT,(int) $4,FALSE);
1667 }
1668 ;
1669
1670 slStringVariable:
1671 SCRL_STRING
1672 SCRL_IDENTIFIER_VALUE
1673 {
1674 newVariable($2,TYPE_STRING,1,FALSE);
1675 }
1676 |
1677 SCRL_STRING
1678 SCRL_IDENTIFIER_VALUE
1679 SCRL_OPEN_SQR_PARANTHESIS
1680 SCRL_FLOAT_VALUE
1681 SCRL_CLOSE_SQR_PARANTHESIS
1682 {
1683 newVariable($2,TYPE_STRING,(int) $4,FALSE);
1684 }
1685 ;
1686
1687 slVectorVariable:
1688 SCRL_VECTOR
1689 SCRL_IDENTIFIER_VALUE
1690 {
1691 newVariable($2,TYPE_VECTOR,1,FALSE);
1692 }
1693 |
1694 SCRL_VECTOR
1695 SCRL_IDENTIFIER_VALUE
1696 SCRL_OPEN_SQR_PARANTHESIS
1697 SCRL_FLOAT_VALUE
1698 SCRL_CLOSE_SQR_PARANTHESIS
1699 {
1700 newVariable($2,TYPE_VECTOR,(int) $4,FALSE);
1701 }
1702 ;
1703
1704 slColorVariable:
1705 SCRL_COLOR
1706 SCRL_IDENTIFIER_VALUE
1707 {
1708 newVariable($2,TYPE_COLOR,1,FALSE);
1709 }
1710 |
1711 SCRL_COLOR
1712 SCRL_IDENTIFIER_VALUE
1713 SCRL_OPEN_SQR_PARANTHESIS
1714 SCRL_FLOAT_VALUE
1715 SCRL_CLOSE_SQR_PARANTHESIS
1716 {
1717 newVariable($2,TYPE_COLOR,(int) $4,FALSE);
1718 }
1719 ;
1720
1721 slNormalVariable:
1722 SCRL_NORMAL
1723 SCRL_IDENTIFIER_VALUE
1724 {
1725 newVariable($2,TYPE_NORMAL,1,FALSE);
1726 }
1727 |
1728 SCRL_NORMAL
1729 SCRL_IDENTIFIER_VALUE
1730 SCRL_OPEN_SQR_PARANTHESIS
1731 SCRL_FLOAT_VALUE
1732 SCRL_CLOSE_SQR_PARANTHESIS
1733 {
1734 newVariable($2,TYPE_NORMAL,(int) $4,FALSE);
1735 }
1736 ;
1737
1738 slPointVariable:
1739 SCRL_POINT
1740 SCRL_IDENTIFIER_VALUE
1741 {
1742 newVariable($2,TYPE_POINT,1,FALSE);
1743 }
1744 |
1745 SCRL_POINT
1746 SCRL_IDENTIFIER_VALUE
1747 SCRL_OPEN_SQR_PARANTHESIS
1748 SCRL_FLOAT_VALUE
1749 SCRL_CLOSE_SQR_PARANTHESIS
1750 {
1751 newVariable($2,TYPE_POINT,(int) $4,FALSE);
1752 }
1753 ;
1754
1755 slMatrixVariable:
1756 SCRL_MATRIX
1757 SCRL_IDENTIFIER_VALUE
1758 {
1759 newVariable($2,TYPE_MATRIX,1,FALSE);
1760 }
1761 |
1762 SCRL_MATRIX
1763 SCRL_IDENTIFIER_VALUE
1764 SCRL_OPEN_SQR_PARANTHESIS
1765 SCRL_FLOAT_VALUE
1766 SCRL_CLOSE_SQR_PARANTHESIS
1767 {
1768 newVariable($2,TYPE_MATRIX,(int) $4,FALSE);
1769 }
1770 ;
1771
1772 slInit: SCRL_INIT
1773 SCRL_NL
1774 {
1775 currentData.parsingInit = TRUE;
1776 newLabel(initLabel,FALSE);
1777 }
1778 slShaderLine
1779 ;
1780
1781 slCode: SCRL_CODE
1782 SCRL_NL
1783 {
1784 currentData.parsingInit = FALSE;
1785 newLabel(codeLabel,FALSE);
1786 }
1787 slShaderLine
1788 ;
1789
1790 slShaderLine:
1791 slShaderLine
1792 slStatement
1793 SCRL_NL
1794 |
1795 slShaderLine
1796 slLabelDefinition
1797 SCRL_NL
1798 |
1799 slShaderLine
1800 slDSO
1801 SCRL_NL
1802 |
1803 ;
1804
1805
1806 slDSO: SCRL_DSO
1807 SCRL_IDENTIFIER_VALUE
1808 {
1809 char *dsoName = $2;
1810
1811 switch(currentData.passNumber) {
1812 case 1:
1813 currentData.numCode++; // opcode
1814 break;
1815 case 2:
1816 strcpy(currentData.currentOpcode,$2);
1817 currentData.currentArgument = 0;
1818 currentData.currentOpcodePlace->arguments = currentData.currentArgumentPlace;
1819 currentData.currentPrototype[0] = '~';
1820 currentData.opcodeUniform = TRUE;
1821 break;
1822 default:
1823 break;
1824 }
1825 }
1826 SCRL_OPEN_PARANTHESIS
1827 SCRL_TEXT_VALUE
1828 SCRL_CLOSE_PARANTHESIS
1829 slOperandList
1830 {
1831 switch(currentData.passNumber) {
1832 case 1:
1833 break;
1834 case 2:
1835 // Set the opcode here
1836 CDSO *dso;
1837
1838 if ((dso = CRenderer::getDSO($2,$5)) != NULL) {
1839 // Save the DSO opcode
1840 if ($5[0] == 'o') currentData.currentOpcodePlace->opcode = FUNCTION_DSO_VOID;
1841 else currentData.currentOpcodePlace->opcode = FUNCTION_DSO;
1842
1843 assert(currentData.opcodeUniform < 256);
1844
1845 currentData.currentOpcodePlace->numArguments = (unsigned char) (currentData.currentArgument);
1846 currentData.currentOpcodePlace->uniform = (unsigned char) (currentData.opcodeUniform);
1847 currentData.currentOpcodePlace->dso = dso;
1848 currentData.currentOpcodePlace++;
1849 } else {
1850 slerror("Failed to locate DSO function\n");
1851 }
1852 break;
1853 default:
1854 break;
1855 }
1856 }
1857 ;
1858
1859 slOpcode:
1860 SCRL_IDENTIFIER_VALUE
1861 {
1862 switch(currentData.passNumber) {
1863 case 1:
1864 currentData.numCode++; // opcode
1865 break;
1866 case 2:
1867 strcpy(currentData.currentOpcode,$1);
1868 currentData.currentArgument = 0;
1869 currentData.currentOpcodePlace->arguments = currentData.currentArgumentPlace;
1870 currentData.currentPrototype[0] = '~';
1871 currentData.opcodeUniform = TRUE;
1872 break;
1873 default:
1874 break;
1875 }
1876 }
1877 |
1878 SCRL_SURFACE
1879 {
1880 switch(currentData.passNumber) {
1881 case 1:
1882 currentData.numCode++; // opcode
1883 break;
1884 case 2:
1885 strcpy(currentData.currentOpcode,"surface");
1886 currentData.currentArgument = 0;
1887 currentData.currentOpcodePlace->arguments = currentData.currentArgumentPlace;
1888 currentData.currentPrototype[0] = '~';
1889 currentData.opcodeUniform = TRUE;
1890 break;
1891 default:
1892 break;
1893 }
1894 }
1895 |
1896 SCRL_DISPLACEMENT
1897 {
1898 switch(currentData.passNumber) {
1899 case 1:
1900 currentData.numCode++; // opcode
1901 break;
1902 case 2:
1903 strcpy(currentData.currentOpcode,"displacement");
1904 currentData.currentArgument = 0;
1905 currentData.currentOpcodePlace->arguments = currentData.currentArgumentPlace;
1906 currentData.currentPrototype[0] = '~';
1907 currentData.opcodeUniform = TRUE;
1908 break;
1909 default:
1910 break;
1911 }
1912 }
1913 ;
1914
1915 slOperandList:
1916 slOperand
1917 slOperandList
1918 {
1919 }
1920 |
1921 {
1922 }
1923 ;
1924
1925 slStatement:
1926 slOpcode
1927 slOperandList
1928 {
1929 setOpcode();
1930 }
1931 ;
1932
1933 slLabelDefinition:
1934 SCRL_LABEL_VALUE
1935 SCRL_COLON
1936 {
1937 newLabel($1,FALSE);
1938 }
1939 ;
1940
1941 slOperand:
1942 SCRL_TEXT_VALUE
1943 {
1944 char *str = $1;
1945
1946 addStringReference(&str,1);
1947 }
1948 |
1949 SCRL_LABEL_VALUE
1950 {
1951 newLabel($1,TRUE);
1952 }
1953 |
1954 SCRL_IDENTIFIER_VALUE
1955 {
1956 addVariableReference($1);
1957 }
1958 |
1959 SCRL_FLOAT_VALUE
1960 {
1961 addFloatReference(&$1,1);
1962 }
1963 |
1964 SCRL_OPEN_PARANTHESIS
1965 SCRL_FLOAT_VALUE
1966 SCRL_COMMA
1967 SCRL_FLOAT_VALUE
1968 SCRL_COMMA
1969 SCRL_FLOAT_VALUE
1970 SCRL_CLOSE_PARANTHESIS
1971 {
1972 vector tmp;
1973
1974 tmp[0] = $2;
1975 tmp[1] = $4;
1976 tmp[2] = $6;
1977
1978 addFloatReference(tmp,3);
1979 }
1980 |
1981 SCRL_OPEN_PARANTHESIS
1982 SCRL_FLOAT_VALUE
1983 SCRL_COMMA
1984 SCRL_FLOAT_VALUE
1985 SCRL_COMMA
1986 SCRL_FLOAT_VALUE
1987 SCRL_COMMA
1988 SCRL_FLOAT_VALUE
1989 SCRL_COMMA
1990 SCRL_FLOAT_VALUE
1991 SCRL_COMMA
1992 SCRL_FLOAT_VALUE
1993 SCRL_COMMA
1994 SCRL_FLOAT_VALUE
1995 SCRL_COMMA
1996 SCRL_FLOAT_VALUE
1997 SCRL_COMMA
1998 SCRL_FLOAT_VALUE
1999 SCRL_COMMA
2000 SCRL_FLOAT_VALUE
2001 SCRL_COMMA
2002 SCRL_FLOAT_VALUE
2003 SCRL_COMMA
2004 SCRL_FLOAT_VALUE
2005 SCRL_COMMA
2006 SCRL_FLOAT_VALUE
2007 SCRL_COMMA
2008 SCRL_FLOAT_VALUE
2009 SCRL_COMMA
2010 SCRL_FLOAT_VALUE
2011 SCRL_COMMA
2012 SCRL_FLOAT_VALUE
2013 SCRL_CLOSE_PARANTHESIS
2014 {
2015 matrix tmp;
2016
2017 tmp[element(0,0)] = $2;
2018 tmp[element(0,1)] = $4;
2019 tmp[element(0,2)] = $6;
2020 tmp[element(0,3)] = $8;
2021 tmp[element(1,0)] = $10;
2022 tmp[element(1,1)] = $12;
2023 tmp[element(1,2)] = $14;
2024 tmp[element(1,3)] = $16;
2025 tmp[element(2,0)] = $18;
2026 tmp[element(2,1)] = $20;
2027 tmp[element(2,2)] = $22;
2028 tmp[element(2,3)] = $24;
2029 tmp[element(3,0)] = $26;
2030 tmp[element(3,1)] = $28;
2031 tmp[element(3,2)] = $30;
2032 tmp[element(3,3)] = $32;
2033
2034 addFloatReference(tmp,16);
2035 }
2036 |
2037 SCRL_OPEN_PARANTHESIS
2038 SCRL_TEXT_VALUE
2039 SCRL_CLOSE_PARANTHESIS
2040 {
2041 strcpy(currentData.currentPrototype,$2);
2042 }
2043 ;
2044
2045 %%
2046 #include "lex.sl.cpp"
2047
2048 int slLineno = 0;
2049
2050 ///////////////////////////////////////////////////////////////////////
2051 // Function : slerror
2052 // Description : Parser error function
2053 // Return Value :
2054 // Comments :
slerror(const char * s)2055 void slerror(const char *s) {
2056 warning(CODE_BADFILE,"Error in shader \"%s\" (%d) (\"%s\") (v%d.%d.%d)\n",currentData.name,slLineno,s,VERSION_RELEASE,VERSION_BETA,VERSION_ALPHA);
2057 currentData.numErrors++;
2058 }
2059
2060
2061 ///////////////////////////////////////////////////////////////////////
2062 // Function : parseShader
2063 // Description : Parse a shader
2064 // Return Value : Parsed shader if successful
2065 // Comments :
parseShader(const char * shaderName,const char * name)2066 CShader *parseShader(const char *shaderName,const char *name) {
2067 YY_BUFFER_STATE oldState;
2068
2069 FILE *fin;
2070
2071 fin = fopen(name,"r");
2072
2073 if (fin == NULL) return NULL;
2074
2075 oldState = YY_CURRENT_BUFFER;
2076 sl_switch_to_buffer(sl_create_buffer( fin, YY_BUF_SIZE ) );
2077
2078 slLineno = 0;
2079
2080 slin = fin;
2081
2082 reset();
2083 currentData.name = name;
2084 currentData.passNumber = 1;
2085
2086 // The first pass
2087 memBegin(CRenderer::globalMemory);
2088 slparse();
2089 memEnd(CRenderer::globalMemory);
2090
2091 if (currentData.numErrors != 0) {
2092 sl_delete_buffer( YY_CURRENT_BUFFER );
2093 fclose(fin);
2094 sl_switch_to_buffer( oldState );
2095 return NULL;
2096 }
2097
2098 slLineno = 0;
2099
2100 fseek(fin,0,SEEK_SET);
2101 alloc();
2102 currentData.passNumber = 2;
2103
2104 // The second pass
2105 memBegin(CRenderer::globalMemory);
2106 slparse();
2107 memEnd(CRenderer::globalMemory);
2108
2109 if (currentData.numErrors != 0) {
2110 reset();
2111 sl_delete_buffer( YY_CURRENT_BUFFER );
2112 fclose(fin);
2113 sl_switch_to_buffer( oldState );
2114 return NULL;
2115 } else {
2116 CShader *cShader = shaderCreate(shaderName);
2117 reset();
2118 sl_delete_buffer( YY_CURRENT_BUFFER );
2119 fclose(fin);
2120 sl_switch_to_buffer( oldState );
2121 return cShader;
2122 }
2123 }
2124
2125 ///////////////////////////////////////////////////////////////////////
2126 // Function : reset
2127 // Description : Deallocate any previously allocated memory for the shader
2128 // Return Value : -
2129 // Comments :
reset()2130 void reset() {
2131 if (currentData.strings != NULL) {
2132 int i;
2133
2134 for (i=0;i<currentData.numStrings;i++)
2135 if (currentData.strings[i] != NULL)
2136 free(currentData.strings[i]);
2137 }
2138
2139
2140 if (currentData.definedVariables != NULL) {
2141 TSlVariable *cVar,*nVar;
2142
2143 for (cVar=currentData.definedVariables;cVar != NULL;) {
2144 nVar = cVar->next;
2145 delete cVar;
2146 cVar = nVar;
2147
2148 // FIXME: Clear the parameter if not NULL
2149 }
2150 }
2151
2152
2153 if (currentData.labelDefinitions != NULL) {
2154 TSlLabel *cLabel,*nLabel;
2155
2156 for (cLabel=currentData.labelDefinitions;cLabel != NULL;) {
2157 nLabel = cLabel->next;
2158 delete cLabel;
2159 cLabel = nLabel;
2160 }
2161 }
2162
2163 if (currentData.labelReferences != NULL) {
2164 TSlLabel *cLabel,*nLabel;
2165
2166 for (cLabel=currentData.labelReferences;cLabel != NULL;) {
2167 nLabel = cLabel->next;
2168 delete cLabel;
2169 cLabel = nLabel;
2170 }
2171 }
2172
2173 if (currentData.memory != NULL) delete [] currentData.memory;
2174
2175 // Clear currentData
2176 memset(¤tData,0,sizeof(TShaderData));
2177 }
2178
2179 ///////////////////////////////////////////////////////////////////////
2180 // Function : alloc
2181 // Description : Allocate required space for the shader
2182 // Return Value :
2183 // Comments :
alloc()2184 void alloc() {
2185 char *mem;
2186
2187 currentData.memory = (char *) allocate_untyped( currentData.numCode*sizeof(TCode) +
2188 currentData.numArgument*sizeof(TArgument) +
2189 currentData.constantSize +
2190 currentData.numConstants*sizeof(void *) +
2191 currentData.numVariables*sizeof(int) +
2192 currentData.numStrings*sizeof(char *));
2193
2194 mem = currentData.memory;
2195
2196 if (currentData.numCode != 0) {
2197 currentData.code = (TCode *) mem;
2198 currentData.currentOpcodePlace = currentData.code;
2199 mem += currentData.numCode*sizeof(TCode);
2200 }
2201
2202 if (currentData.numArgument != 0) {
2203 currentData.arguments = (TArgument *) mem;
2204 currentData.currentArgumentPlace = currentData.arguments;
2205 mem += currentData.numArgument*sizeof(TArgument);
2206 }
2207
2208 if (currentData.constantSize != 0) {
2209 currentData.constants = mem;
2210 mem += currentData.constantSize;
2211 }
2212
2213 if (currentData.numConstants != 0) {
2214 currentData.constantEntries = (void **) mem;
2215 mem += currentData.numConstants*sizeof(void *);
2216 }
2217
2218 if (currentData.numVariables != 0) {
2219 currentData.varyingSizes = (int *) mem;
2220 mem += currentData.numVariables*sizeof(int);
2221 }
2222
2223 if (currentData.numStrings != 0) {
2224 int i;
2225
2226 currentData.strings = (char **) mem;
2227 mem += currentData.numStrings*sizeof(char *);
2228
2229 for (i=0;i<currentData.numStrings;i++) {
2230 currentData.strings[i] = NULL;
2231 }
2232 }
2233 }
2234
2235 ///////////////////////////////////////////////////////////////////////
2236 // Function : shaderCreate
2237 // Description : Parse successful, allocate the shader
2238 // Return Value :
2239 // Comments :
shaderCreate(const char * shaderName)2240 CShader *shaderCreate(const char *shaderName) {
2241 CShader *cShader;
2242
2243 // Sanity check for the shaders
2244 assert(currentData.numConstants == currentData.currentConstant);
2245 assert(currentData.numVariables == currentData.currentVariable);
2246 assert(currentData.numStrings == currentData.currentString);
2247 assert(currentData.constantSize == currentData.currentConstantSize);
2248 assert(currentData.varyingSize == currentData.currentVaryingSize);
2249 assert((currentData.currentOpcodePlace - currentData.code) == currentData.numCode);
2250 assert((currentData.currentArgumentPlace - currentData.arguments) == currentData.numArgument);
2251
2252 // Fix the labels
2253 {
2254 TSlLabel *cLabel,*nLabel;
2255
2256 for (cLabel = currentData.labelReferences;cLabel != NULL;cLabel = cLabel->next) {
2257 for (nLabel = currentData.labelDefinitions;nLabel != NULL;nLabel = nLabel->next) {
2258 if (strcmp(cLabel->name,nLabel->name) == 0) {
2259 cLabel->argument->index = nLabel->index;
2260 break;
2261 }
2262 }
2263
2264 if (nLabel == NULL) {
2265 slerror("Label not found");
2266 return NULL;
2267 }
2268 }
2269
2270 for (cLabel = currentData.labelDefinitions;cLabel != NULL;cLabel = cLabel->next) {
2271 if (strcmp(cLabel->name,codeLabel) == 0) {
2272 currentData.codeEntryPoint = cLabel->index;
2273 }
2274
2275 if (strcmp(cLabel->name,initLabel) == 0) {
2276 currentData.initEntryPoint = cLabel->index;
2277 }
2278 }
2279 }
2280
2281 cShader = new CShader(shaderName);
2282
2283 cShader->memory = currentData.memory;
2284
2285 cShader->codeArea = currentData.code;
2286
2287 cShader->constantEntries = currentData.constantEntries;
2288 cShader->varyingSizes = currentData.varyingSizes;
2289
2290 cShader->strings = currentData.strings;
2291
2292 cShader->numStrings = currentData.numStrings;
2293 cShader->numVariables = currentData.numVariables;
2294
2295 cShader->codeEntryPoint = currentData.codeEntryPoint;
2296 cShader->initEntryPoint = currentData.initEntryPoint;
2297
2298 cShader->usedParameters = currentData.usedParameters;
2299
2300 cShader->type = currentData.shaderType;
2301
2302 {
2303 TSlVariable *cVar;
2304 int i,numGlobals=0;
2305
2306 cShader->parameters = NULL;
2307 i = 0;
2308 while(currentData.definedVariables != NULL) {
2309 cVar = currentData.definedVariables;
2310 currentData.definedVariables = cVar->next;
2311
2312 // Is this a parameter ?
2313 if (cVar->variable != NULL) {
2314 cVar->variable->next = cShader->parameters;
2315 cShader->parameters = cVar->variable;
2316 if (cVar->variable->storage == STORAGE_GLOBAL ||
2317 cVar->variable->storage == STORAGE_MUTABLEPARAMETER)
2318 numGlobals++;
2319 }
2320
2321 // Delete the variable
2322 delete cVar;
2323 i++;
2324 }
2325
2326 cShader->numGlobals = numGlobals;
2327 }
2328
2329 cShader->analyse();
2330
2331
2332 currentData.memory = NULL;
2333 currentData.code = NULL;
2334 currentData.constants = NULL;
2335 currentData.varyingSizes = NULL;
2336 currentData.strings = NULL;
2337 currentData.constantEntries = NULL;
2338
2339
2340 return cShader;
2341 }
2342
2343
2344 extern void convertColorFrom(float *out,const float *in,ECoordinateSystem s);
2345
2346