private AsmDcl[] ExtractOuputs() { List <AsmDcl> dclList = new List <AsmDcl>(); if (commands.Length > 0 && commands[0].Target.Length == 6 && commands[0].Target.StartsWith("vs_3_")) { //vs_3_0 is the odd one out here, using dcl_position0.. style declarations for (int i = 0; i < this.commands.Length; i++) { if (this.commands[i].Target.Length > 4 && this.commands[i].Target.Substring(0, 4) == "dcl_") { //it's an output, or an input.. //if it's an output, it'll have one arg, going to an oX register if (this.commands[i].OpCount == 1) { AsmOp op = this.commands[i].GetOp(0); if (op.TokenCount >= 1) { string token = op.GetToken(0); if (token.Length > 1 && token[0] == 'o' && char.IsNumber(token[1])) { //it's an output! AsmDcl output; if (AsmDcl.Parse(this.commands[i].Target.Substring(4), out output)) { dclList.Add(output); } } } } } } } else { //all others just use registers with funky names. //oPos - VS position out //oTXX - VS tex out //oD0, oD1 - VS colour out //oCX - PS colour out //oDepth - PS depth out //loop through all the commands, for (int c = 0; c < commands.Length; c++) { //loop their args for (int i = 0; i < commands[c].OpCount; i++) { AsmOp op = commands[c].GetOp(i); //find any that point to the special 'o' args string reg = null; if (op.TokenCount > 0) { reg = op.GetToken(0); if (reg.Length == 1 && reg[0] == '-' && op.TokenCount > 1) { reg = op.GetToken(1); } if (reg.Length > 1 && reg[0] == 'o') { AsmDcl?dcl = null; //here we go. found an output. if (reg.Length == 4 && reg == "oPos") { dcl = new AsmDcl(VertexElementUsage.Position, 0); } if (reg.Length == 6 && reg == "oDepth") { dcl = new AsmDcl(VertexElementUsage.Depth, 0); } if (reg.Length == 3 && (reg[1] == 'D' || reg[1] == 'C') && char.IsNumber(reg[2])) { dcl = new AsmDcl(VertexElementUsage.Color, byte.Parse(reg[2].ToString())); } if (reg.Length == 3 && reg[1] == 'T' && char.IsNumber(reg[2])) { dcl = new AsmDcl(VertexElementUsage.TextureCoordinate, byte.Parse(reg[2].ToString())); } if (reg.Length == 4 && reg[1] == 'T' && char.IsNumber(reg[2]) && char.IsNumber(reg[3])) { dcl = new AsmDcl(VertexElementUsage.TextureCoordinate, byte.Parse(reg.Substring(2))); } if (dcl != null && dclList.Contains(dcl.Value) == false) { dclList.Add(dcl.Value); } } } } } } dclList.Sort(); return(dclList.ToArray()); }
private AsmDcl[] ExtractInputs() { List <AsmDcl> inputs = new List <AsmDcl>(); if (commands.Length > 0 && commands[0].Target.Length == 6 && commands[0].Target.StartsWith("ps_2_")) { //logic is quite different for ps_2_x //instead of dcl_texcoord0 v0 //you get: //dcl t0 //or //dcl v0 //for colour for (int i = 0; i < this.commands.Length; i++) { if (this.commands[i].Target.Length == 3 && this.commands[i].Target == "dcl") { //if it's an output, it'll have one arg, going to a tX or vX register if (this.commands[i].OpCount == 1) { AsmOp op = this.commands[i].GetOp(0); if (op.TokenCount >= 1) { byte index; string token = op.GetToken(0); if (token.Length > 1 && (token[0] == 'v' || token[0] == 't') && char.IsNumber(token[1]) && byte.TryParse(token.Substring(1), out index)) { if (token[0] == 'v') // colour { inputs.Add(new AsmDcl(VertexElementUsage.Color, index)); } else { inputs.Add(new AsmDcl(VertexElementUsage.TextureCoordinate, index)); } } } } } } } else { for (int i = 0; i < this.commands.Length; i++) { if (this.commands[i].Target.Length > 4 && this.commands[i].Target.Substring(0, 4) == "dcl_") { //it's an output, or an input.. //if it's an input, it'll have one arg, going to an vX register if (this.commands[i].OpCount == 1) { AsmOp op = this.commands[i].GetOp(0); if (op.TokenCount >= 1) { string token = op.GetToken(0); if (token.Length > 1 && token[0] == 'v' && char.IsNumber(token[1])) { //it's an input! AsmDcl input; if (AsmDcl.Parse(this.commands[i].Target.Substring(4), out input)) { inputs.Add(input); } } } } } } } inputs.Sort(); return(inputs.ToArray()); }
public bool ContainsOutput(AsmDcl dcl) { return(Array.BinarySearch(this.dclOut, dcl) >= 0); }