private void RebuildCommands() { PICACommandWriter Writer = new PICACommandWriter(); PICARegister Register = PICARegister.GPUREG_DUMMY; switch (StageIndex) { case 0: Register = PICARegister.GPUREG_TEXENV0_SOURCE; break; case 1: Register = PICARegister.GPUREG_TEXENV1_SOURCE; break; case 2: Register = PICARegister.GPUREG_TEXENV2_SOURCE; break; case 3: Register = PICARegister.GPUREG_TEXENV3_SOURCE; break; case 4: Register = PICARegister.GPUREG_TEXENV4_SOURCE; break; case 5: Register = PICARegister.GPUREG_TEXENV5_SOURCE; break; } Writer.SetCommand(Register, true, Stage.Source.ToUInt32(), Stage.Operand.ToUInt32(), Stage.Combiner.ToUInt32(), Stage.Color.ToUInt32(), Stage.Scale.ToUInt32()); Commands = Writer.GetBuffer(); }
bool ICustomSerialization.Serialize(BinarySerializer Serializer) { PICARegister[] Cmd0 = new PICARegister[] { PICARegister.GPUREG_TEXUNIT0_TYPE, PICARegister.GPUREG_TEXUNIT1_TYPE, PICARegister.GPUREG_TEXUNIT2_TYPE }; PICARegister[] Cmd1 = new PICARegister[] { PICARegister.GPUREG_TEXUNIT0_BORDER_COLOR, PICARegister.GPUREG_TEXUNIT1_BORDER_COLOR, PICARegister.GPUREG_TEXUNIT2_BORDER_COLOR }; PICACommandWriter Writer = new PICACommandWriter(); uint Filter; Filter = ((uint)MagFilter & 1) << 1; Filter |= ((uint)MinFilter & 1) << 2; Filter |= ((uint)MipFilter & 1) << 24; Filter |= ((uint)WrapV & 7) << 8; Filter |= ((uint)WrapU & 7) << 12; uint LOD; LOD = (uint)((int)(LODBias * 0x100) & 0x1fff); LOD |= ((uint)MinLOD & 0xf) << 24; Writer.SetCommand(Cmd0[MapperIndex], 0, 1); Writer.SetCommand(Cmd1[MapperIndex], true, BorderColor.ToUInt32(), 0, Filter, LOD, 0, 0, 0, 0, 0, 0); Commands = Writer.GetBuffer(); CommandsLength = Commands.Length * 4; //TODO: Don't assume it uses the Standard sampler, could be the Shadow sampler too GfxTextureSamplerStd Samp = (GfxTextureSamplerStd)Sampler; Samp.LODBias = LODBias; Samp.BorderColor = BorderColor.ToVector4(); Samp.MinFilter = GetMinFilter(); return(false); }
bool ICustomSerialization.Serialize(BinarySerializer Serializer) { PICACommandWriter Writer = new PICACommandWriter(); Writer.SetCommand(PICARegister.GPUREG_FRAGOP_ALPHA_TEST, Test.ToUInt32()); Commands = Writer.GetBuffer(); return(false); }
private void RebuildCommands() { PICACommandWriter Writer = new PICACommandWriter(); Writer.SetCommand(PICARegister.GPUREG_STENCIL_TEST, Test.ToUInt32(), 13); Writer.SetCommand(PICARegister.GPUREG_STENCIL_OP, Operation.ToUInt32()); Commands = Writer.GetBuffer(); }
bool ICustomSerialization.Serialize(BinarySerializer Serializer) { PICACommandWriter Writer = new PICACommandWriter(); uint CullMode = (uint)FaceCulling.ToPICAFaceCulling() & 3; Writer.SetCommand(PICARegister.GPUREG_FACECULLING_CONFIG, CullMode, 1); FaceCullingCommand = Writer.GetBuffer(); return(false); }
bool ICustomSerialization.Serialize(BinarySerializer Serializer) { PICACommandWriter Writer = new PICACommandWriter(); uint UpdateColor = 0; if (TextureEnvironments[1].Stage.UpdateColorBuffer) { UpdateColor |= 0x100; } if (TextureEnvironments[2].Stage.UpdateColorBuffer) { UpdateColor |= 0x200; } if (TextureEnvironments[3].Stage.UpdateColorBuffer) { UpdateColor |= 0x400; } if (TextureEnvironments[4].Stage.UpdateColorBuffer) { UpdateColor |= 0x800; } if (TextureEnvironments[1].Stage.UpdateAlphaBuffer) { UpdateColor |= 0x1000; } if (TextureEnvironments[2].Stage.UpdateAlphaBuffer) { UpdateColor |= 0x2000; } if (TextureEnvironments[3].Stage.UpdateAlphaBuffer) { UpdateColor |= 0x4000; } if (TextureEnvironments[4].Stage.UpdateAlphaBuffer) { UpdateColor |= 0x8000; } Writer.SetCommand(PICARegister.GPUREG_TEXENV_BUFFER_COLOR, TexEnvBufferColor.ToUInt32()); Writer.SetCommand(PICARegister.GPUREG_TEXENV_UPDATE_BUFFER, UpdateColor, 2); Writer.SetCommand(PICARegister.GPUREG_LIGHTING_CONFIG0, 0x400u, 2); Commands = Writer.GetBuffer(); TexEnvBufferColorF = TexEnvBufferColor.ToVector4(); return(false); }
bool ICustomSerialization.Serialize(BinarySerializer Serializer) { PICACommandWriter Writer = new PICACommandWriter(); uint LogicalOp = (uint)LogicalOperation & 0xf; Writer.SetCommand(PICARegister.GPUREG_COLOR_OPERATION, true, ColorOperation.ToUInt32(), Function.ToUInt32(), LogicalOp, Color.ToUInt32()); Commands = new uint[6]; Buffer.BlockCopy(Writer.GetBuffer(), 0, Commands, 0, 5); Commands = Writer.GetBuffer(); ColorF = Color.ToVector4(); return(false); }
bool ICustomSerialization.Serialize(BinarySerializer Serializer) { PICACommandWriter Writer = new PICACommandWriter(); uint ZDepth; if ((uint)ColorMask.DepthFunc > 1) { ZDepth = (uint)ColorMask.DepthFunc > 5 ? 2u : 3u; } else { ZDepth = (uint)ColorMask.DepthFunc; } Writer.SetCommand(PICARegister.GPUREG_DEPTH_COLOR_MASK, ColorMask.ToUInt32(), 1); Writer.SetCommand(PICARegister.GPUREG_GAS_DELTAZ_DEPTH, ZDepth << 24, 8); Commands = Writer.GetBuffer(); return(false); }
public void Write(BinaryWriter Writer) { long StartPosition = Writer.BaseStream.Position; new GFSection(MagicStr).Write(Writer); GFNV1 FNV = new GFNV1(); FNV.Hash(Name); Writer.Write(FNV.HashCode); Writer.WritePaddedString(Name, 0x40); Writer.Write(0u); Writer.Write(BBoxMinVector); Writer.Write(BBoxMaxVector); Writer.Write((uint)SubMeshes.Count); Writer.Write(BoneIndicesPerVertex); Writer.Write(0xfffffffffffffffful); Writer.Write(0xfffffffffffffffful); for (int Index = 0; Index < SubMeshes.Count; Index++) { GFSubMesh SM = SubMeshes[Index]; PICACommandWriter CmdWriter; /* Enable commands */ CmdWriter = new PICACommandWriter(); ulong BufferFormats = 0; ulong BufferAttributes = 0; ulong BufferPermutation = 0; int AttributesTotal = 0; //Normal Attributes for (int Attr = 0; Attr < SM.Attributes.Count; Attr++) { PICAAttribute Attrib = SM.Attributes[Attr]; int Shift = AttributesTotal++ *4; ulong AttribFmt; AttribFmt = (ulong)Attrib.Format; AttribFmt |= (ulong)((Attrib.Elements - 1) & 3) << 2; BufferFormats |= AttribFmt << Shift; BufferPermutation |= (ulong)Attrib.Name << Shift; BufferAttributes |= (ulong)Attr << Shift; } BufferAttributes |= (ulong)(SM.VertexStride & 0xff) << 48; BufferAttributes |= (ulong)SM.Attributes.Count << 60; //Fixed Attributes foreach (PICAFixedAttribute Attrib in SM.FixedAttributes) { BufferFormats |= 1ul << (48 + AttributesTotal); BufferPermutation |= (ulong)Attrib.Name << AttributesTotal++ *4; } BufferFormats |= (ulong)(AttributesTotal - 1) << 60; CmdWriter.SetCommand(PICARegister.GPUREG_VSH_INPUTBUFFER_CONFIG, 0xa0000000u | (uint)(AttributesTotal - 1), 0xb); CmdWriter.SetCommand(PICARegister.GPUREG_VSH_NUM_ATTR, (uint)(AttributesTotal - 1), 1); CmdWriter.SetCommand(PICARegister.GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW, (uint)(BufferPermutation >> 0)); CmdWriter.SetCommand(PICARegister.GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH, (uint)(BufferPermutation >> 32)); CmdWriter.SetCommand(PICARegister.GPUREG_ATTRIBBUFFERS_LOC, true, 0x03000000u, //Base Address (Place holder) (uint)(BufferFormats >> 0), (uint)(BufferFormats >> 32), 0x99999999u, //Attributes Buffer Address (Place holder) (uint)(BufferAttributes >> 0), (uint)(BufferAttributes >> 32)); for (int Attr = 0; Attr < SM.FixedAttributes.Count; Attr++) { PICAFixedAttribute Attrib = SM.FixedAttributes[Attr]; float Scale = Attrib.Name == PICAAttributeName.Color || Attrib.Name == PICAAttributeName.BoneWeight ? GFMesh.Scales[1] : 1; PICAFixedAttribute ScaledAttribute = new PICAFixedAttribute() { Name = Attrib.Name, Value = new PICAVectorFloat24(Attrib.Value.X, Attrib.Value.Y, Attrib.Value.Z, Attrib.Value.W) / Scale }; CmdWriter.SetCommand(PICARegister.GPUREG_FIXEDATTRIB_INDEX, true, (uint)(SM.Attributes.Count + Attr), ScaledAttribute.Value.Word0, ScaledAttribute.Value.Word1, ScaledAttribute.Value.Word2); } CmdWriter.WriteEnd(); WriteCmdsBuff(Writer, CmdWriter.GetBuffer(), Index * 3); /* Disable commands */ CmdWriter = new PICACommandWriter(); //Assuming that the Position isn't used as Fixed Attribute since this doesn't make sense. CmdWriter.SetCommand(PICARegister.GPUREG_ATTRIBBUFFER0_OFFSET, true, 0, 0, 0); for (int Attr = 1; Attr < 12; Attr++) { CmdWriter.SetCommand(PICARegister.GPUREG_ATTRIBBUFFER0_CONFIG2 + Attr * 3, 0); if (SM.FixedAttributes?.Any(x => (int)x.Name == Attr) ?? false) { CmdWriter.SetCommand(PICARegister.GPUREG_FIXEDATTRIB_INDEX, true, (uint)Attr, 0, 0, 0); } } CmdWriter.WriteEnd(); WriteCmdsBuff(Writer, CmdWriter.GetBuffer(), Index * 3 + 1); /* Index commands */ CmdWriter = new PICACommandWriter(); uint IdxFmtAddr = SM.IsIdx8Bits ? 0x01999999u : 0x81999999u; CmdWriter.SetCommand(PICARegister.GPUREG_RESTART_PRIMITIVE, true); CmdWriter.SetCommand(PICARegister.GPUREG_INDEXBUFFER_CONFIG, IdxFmtAddr); CmdWriter.SetCommand(PICARegister.GPUREG_NUMVERTICES, (uint)SM.Indices.Length); CmdWriter.SetCommand(PICARegister.GPUREG_START_DRAW_FUNC0, false, 1); CmdWriter.SetCommand(PICARegister.GPUREG_DRAWELEMENTS, true); CmdWriter.SetCommand(PICARegister.GPUREG_START_DRAW_FUNC0, true, 1); CmdWriter.SetCommand(PICARegister.GPUREG_VTX_FUNC, true); CmdWriter.SetCommand(PICARegister.GPUREG_PRIMITIVE_CONFIG, (uint)SM.PrimitiveMode << 8, 8); CmdWriter.SetCommand(PICARegister.GPUREG_PRIMITIVE_CONFIG, (uint)SM.PrimitiveMode << 8, 8); CmdWriter.WriteEnd(); WriteCmdsBuff(Writer, CmdWriter.GetBuffer(), Index * 3 + 2); } foreach (GFSubMesh SM in SubMeshes) { FNV = new GFNV1(); FNV.Hash(SM.Name); Writer.Write(FNV.HashCode); Writer.Write(GetPaddedLen4(SM.Name.Length)); Writer.WritePaddedString(SM.Name, GetPaddedLen4(SM.Name.Length)); Writer.Write(SM.BoneIndicesCount); byte[] BoneIndices = new byte[0x1f]; SM.BoneIndices.CopyTo(BoneIndices, 0); Writer.Write(BoneIndices); int VerticesCount = 0; if (SM.VertexStride != 0) { VerticesCount = SM.RawBuffer.Length / SM.VertexStride; } int VtxBuffLen = SM.RawBuffer.Length; int IdxBuffLen = SM.Indices.Length * (SM.IsIdx8Bits ? 1 : 2); Writer.Write(VerticesCount); Writer.Write(SM.Indices.Length); Writer.Write(GetPaddedLen16(VtxBuffLen)); Writer.Write(GetPaddedLen16(IdxBuffLen)); } foreach (GFSubMesh SM in SubMeshes) { long Position = Writer.BaseStream.Position; Writer.Write(SM.RawBuffer); int VertexBufferPaddingLength = GetPaddedLen16(SM.RawBuffer.Length) - SM.RawBuffer.Length; Writer.Write(new byte[VertexBufferPaddingLength]); /*while (((Writer.BaseStream.Position - Position) & 3) != 0) * { * Writer.Write((byte)0); * }*/ Position = Writer.BaseStream.Position; foreach (ushort Idx in SM.Indices) { if (SM.IsIdx8Bits) { Writer.Write((byte)Idx); } else { Writer.Write(Idx); } } /*while (((Writer.BaseStream.Position - Position) & 0xf) != 0) * { * Writer.Write((byte)0); * }*/ int IndexBufferLength = SM.Indices.Length * (SM.IsIdx8Bits ? 1 : 2); int IndexBufferPaddingLength = GetPaddedLen16(IndexBufferLength) - IndexBufferLength; Writer.Write(new byte[IndexBufferPaddingLength]); } Writer.Align(0x10, 0); Writer.Write(0ul); Writer.Write(0ul); long EndPosition = Writer.BaseStream.Position; Writer.BaseStream.Seek(StartPosition + 8, SeekOrigin.Begin); Writer.Write((uint)(EndPosition - StartPosition - 0x10)); Writer.BaseStream.Seek(EndPosition, SeekOrigin.Begin); }