bool csPixelShaderParser::ParseProgram (iDataBuffer* program) { version = CS_PS_INVALID; csString prog; prog.Append ((char*)program->GetData(), program->GetSize()); // Trim any leading/trailing blank lines prog.Trim (); size_t len = prog.Length (); if (len == 0) { Report (CS_REPORTER_SEVERITY_ERROR, "Empty program!"); return false; } max_registers[CS_PS_REG_TEX] = 4; max_registers[CS_PS_REG_TEMP] = 2; max_registers[CS_PS_REG_CONSTANT] = 8; max_registers[CS_PS_REG_COLOR] = 2; bool hasVersion = false; csStringReader reader (prog); csString line; int lineCount = 0; while (reader.HasMoreLines ()) { if (!reader.GetLine (line)) break; lineCount++; csPSProgramInstruction inst; if(!GetInstruction (line, inst)) return false; // Probably a blank line or comment ... ignore if(inst.instruction == CS_PS_INS_INVALID) continue; // Identify the version bool isVerInstr = (inst.instruction >= CS_PS_INS_PS_1_1) && (inst.instruction <= CS_PS_INS_PS_1_4); if (!hasVersion) { if (!isVerInstr) { Report (CS_REPORTER_SEVERITY_WARNING, "Expected version, got %s", GetInstructionName (inst.instruction)); return false; } switch (inst.instruction) { case CS_PS_INS_PS_1_1: version = CS_PS_1_1; hasVersion = true; break; case CS_PS_INS_PS_1_2: version = CS_PS_1_2; hasVersion = true; break; case CS_PS_INS_PS_1_3: version = CS_PS_1_3; hasVersion = true; break; case CS_PS_INS_PS_1_4: version = CS_PS_1_4; hasVersion = true; max_registers[CS_PS_REG_TEX] = 6; max_registers[CS_PS_REG_TEMP] = 6; break; default: break; } } else if (isVerInstr) { Report (CS_REPORTER_SEVERITY_WARNING, "Invalid version instruction %s in line %d", GetInstructionName (inst.instruction), lineCount); return false; } if(!(version & PS_Instructions[inst.instruction].versions)) { Report (CS_REPORTER_SEVERITY_ERROR, "Pixel Shader version %s does not support instruction %s", GetVersionString (version), CS::Quote::Single (GetInstructionName (inst.instruction))); return false; } if (!isVerInstr) program_instructions.Push (inst); } return true; }
void OutputNodeData(FILE* aFile, CSyntaxNode* aNode) { fprintf(aFile, "node%p[label=\"", aNode); const char* Format = 0; TNodeData Data = aNode->Data(); switch (Data.Type) { case EInstruction: fprintf(aFile, "instruction %d\\n[ %s ]", (int) Data.Instruction, GetInstructionName((int) Data.Instruction)); Format = StyleInstruction; break; case ENumberConstant: fprintf(aFile, "number %lg", Data.NumberConstant); Format = StyleNumberConstant; break; case EStringConstant: fprintf(aFile, "string \\\""); OutputString(Data.StringConstant.c_str(), aFile); fprintf(aFile, "\\\""); Format = StyleStringConstant; break; case EVariable: fprintf(aFile, "variable %s", Data.Identifier.c_str()); Format = StyleVariable; break; case ELabel: fprintf(aFile, "label %s", Data.Identifier.c_str()); Format = StyleLabel; break; case ENewVariable: fprintf(aFile, "new_variable %s", Data.Identifier.c_str()); Format = StyleNewVariable; break; case ENewLabel: fprintf(aFile, "new_label %s", Data.Identifier.c_str()); Format = StyleNewLabel; break; case EBlank: fprintf(aFile, "blank"); Format = StyleBlank; break; case ENewFunction: fprintf(aFile, "new_function %s", Data.Identifier.c_str()); Format = StyleNewFunction; break; case EFunction: fprintf(aFile, "function %s", Data.Identifier.c_str()); Format = StyleFunction; break; case EParameter: fprintf(aFile, "parameter %s", Data.Identifier.c_str()); Format = StyleParameter; break; case EParameterValue: fprintf(aFile, "parameter_value"); Format = StyleParameterValue; break; default: __THROW("Invalid node type (%d)."); }; fprintf(aFile, "\", %s];\n", Format); }