public static unsafe List <XFData> Parse(VoidPtr address) { List <XFData> XFCmds = new List <XFData>(); byte * pData = (byte *)address; Top: if (*pData++ == 0x10) { XFData dat = new XFData(); int count = *(bushort *)pData; pData += 2; dat._addr = (XFMemoryAddr)(ushort)*(bushort *)pData; pData += 2; dat._values = new List <uint>(); for (int i = 0; i < count + 1; i++) { dat._values.Add(*(buint *)pData); pData += 4; } XFCmds.Add(dat); goto Top; } return(XFCmds); }
public override void OnRebuild(VoidPtr address, int length, bool force) { MDL0Material* header = (MDL0Material*)address; ushort i1 = 0x1040, i2 = 0x1050; int mtx = 0; //Set offsets header->_dataLen = _dataLen = length; int addr = 0; if (Model._version >= 10) { header->_dlOffset = 0; //Fur Data not supported header->_dlOffsetv10p = length - 0x180; if (Children.Count > 0) header->_matRefOffset = addr = 1048; else header->_matRefOffset = 0; } else { header->_dlOffset = length - 0x180; if (Children.Count > 0) header->_matRefOffset = addr = 1044; else header->_matRefOffset = 0; } //Check for user entries if (_userEntries.Count > 0) { addr += Children.Count * 0x34; if (Model._version == 11 || Model._version == 10) header->_dlOffset = addr; else header->_userDataOffset = addr; _userEntries.Write(header->UserData(Model._version)); } else addr = header->_userDataOffset = 0; //Set defaults if the model is an import or the material was created if (Model._isImport || New) { if (New) { _lSet = 20; _fSet = 4; _ssc = 3; C1ColorEnabled = true; C1AlphaMaterialSource = GXColorSrc.Vertex; C1ColorMaterialSource = GXColorSrc.Vertex; C1ColorDiffuseFunction = GXDiffuseFn.Clamped; C1ColorAttenuation = GXAttnFn.Spotlight; C1AlphaEnabled = true; C1AlphaDiffuseFunction = GXDiffuseFn.Clamped; C1AlphaAttenuation = GXAttnFn.Spotlight; C2ColorDiffuseFunction = GXDiffuseFn.Disabled; C2ColorAttenuation = GXAttnFn.None; C2AlphaDiffuseFunction = GXDiffuseFn.Disabled; C2AlphaAttenuation = GXAttnFn.None; } //Set default texgen flags for (int i = 0; i < Children.Count; i++) { MDL0MaterialRefNode node = ((MDL0MaterialRefNode)Children[i]); //Tex Mtx XFData dat = new XFData(); dat.addr = (XFMemoryAddr)i1++; XFTexMtxInfo tex = new XFTexMtxInfo(); tex._data = (uint)(0 | ((int)TexProjection.ST << 1) | ((int)TexInputForm.AB11 << 2) | ((int)TexTexgenType.Regular << 4) | ((int)(0x5) << 7) | (4 << 10) | (2 << 13)); dat.values.Add(tex._data); XFCmds.Add(dat); node.TexMtxFlags = tex; //Dual Tex dat = new XFData(); dat.addr = (XFMemoryAddr)i2++; XFDualTex dtex = new XFDualTex(mtx, 0); mtx += 3; dat.values.Add(dtex.Value); XFCmds.Add(dat); node.DualTexFlags = dtex; node.getValues(); node._texFlags.TexScale = new Vector2(1); node._bindState._scale = new Vector3(1); node._texMatrix.TexMtx = Matrix43.Identity; node._texMatrix.SCNCamera = -1; node._texMatrix.SCNLight = -1; node._texMatrix.MapMode = 0; node._texMatrix.Identity = 1; } } //Set header values header->_numTextures = Children.Count; header->_numTexGens = _numTextures = (byte)Children.Count; header->_index = Index; header->_numLightChans = _numLights; header->_activeTEVStages = (byte)_ssc; header->_numIndTexStages = _clip; header->_enableAlphaTest = _transp; header->_lightSet = _lSet; header->_fogSet = _fSet; header->_pad = 0; header->_cull = (int)_cull; header->_usageFlags = _usageFlags._data; header->_indirectMethod1 = _indirectMethod1; header->_indirectMethod2 = _indirectMethod2; header->_indirectMethod3 = _indirectMethod3; header->_indirectMethod4 = _indirectMethod4; header->_normMapRefLight1 = _normMapRefLight1; header->_normMapRefLight2 = _normMapRefLight2; header->_normMapRefLight3 = _normMapRefLight3; header->_normMapRefLight4 = _normMapRefLight4; //Generate layer flags and write texture matrices MDL0TexSRTData* TexSettings = header->TexMatrices(Model._version); *TexSettings = MDL0TexSRTData.Default; _layerFlags = 0; for (int i = Children.Count - 1; i >= 0; i--) { MDL0MaterialRefNode node = (MDL0MaterialRefNode)Children[i]; node._flags |= TexFlags.Enabled; node._texFlags.TexScale = new Vector2(node._bindState._scale._x, node._bindState._scale._y); node._texFlags.TexRotation = node._bindState._rotate._x; node._texFlags.TexTranslation = new Vector2(node._bindState._translate._x, node._bindState._translate._y); //Check for non-default values if (node._texFlags.TexScale != new Vector2(1)) node._flags &= 0xF - TexFlags.FixedScale; else node._flags |= TexFlags.FixedScale; if (node._texFlags.TexRotation != 0) node._flags &= 0xF - TexFlags.FixedRot; else node._flags |= TexFlags.FixedRot; if (node._texFlags.TexTranslation != new Vector2(0)) node._flags &= 0xF - TexFlags.FixedTrans; else node._flags |= TexFlags.FixedTrans; TexSettings->SetTexFlags(node._texFlags, node.Index); TexSettings->SetTexMatrices(node._texMatrix, node.Index); _layerFlags = ((_layerFlags << 4) | (byte)node._flags); } TexSettings->_layerFlags = _layerFlags; TexSettings->_mtxFlags = _texMtxFlags; //Write lighting flags MDL0MaterialLighting* Light = header->Light(Model._version); Light->Channel1 = _chan1; Light->Channel2 = _chan2; //The shader offset will be written later //Rebuild references MDL0TextureRef* mRefs = header->First; foreach (MDL0MaterialRefNode n in Children) n.Rebuild(mRefs++, 0x34, force); //Set Display Lists *header->TevKonstBlock(Model._version) = _tevKonstBlock; *header->TevColorBlock(Model._version) = _tevColorBlock; *header->IndMtxBlock(Model._version) = _indMtx; mode = header->DisplayLists(Model._version); *mode = MatModeBlock.Default; if (Model._isImport) { _alphaFunc = mode->AlphaFunction; _zMode = mode->ZMode; _blendMode = mode->BlendMode; _constantAlpha = mode->ConstantAlpha; } else { mode->AlphaFunction = _alphaFunc; mode->ZMode = _zMode; mode->BlendMode = _blendMode; mode->ConstantAlpha = _constantAlpha; } //Write XF flags byte* xfData = (byte*)header->DisplayLists(Model._version) + 0xE0; i1 = 0x1040; i2 = 0x1050; mtx = 0; foreach (MDL0MaterialRefNode mr in Children) { //Tex Mtx *xfData++ = 0x10; *(bushort*)xfData = 0; xfData += 2; *(bushort*)xfData = (ushort)i1++; xfData += 2; *(buint*)xfData = mr.TexMtxFlags._data; xfData += 4; //Dual Tex *xfData++ = 0x10; *(bushort*)xfData = 0; xfData += 2; *(bushort*)xfData = (ushort)i2++; xfData += 2; *(buint*)xfData = new XFDualTex(mtx, mr.DualTexFlags.NormalEnable).Value; xfData += 4; mtx += 3; } New = false; }
public override bool OnInitialize() { MDL0Material* header = Header; _initVersion = header->_pad != 0 && _replaced ? header->_pad : Model._version; if ((_name == null) && (header->_stringOffset != 0)) _name = header->ResourceString; XFCmds.Clear(); //Get XF Commands byte* pData = (byte*)header->DisplayLists(Model._version) + 0xE0; Top: if (*pData++ == 0x10) { XFData dat = new XFData(); int count = (ushort)*(bushort*)pData; pData += 2; dat.addr = (XFMemoryAddr)(ushort)*(bushort*)pData; pData += 2; dat.values = new List<uint>(); for (int i = 0; i < count + 1; i++) { dat.values.Add(*(buint*)pData); pData += 4; } XFCmds.Add(dat); goto Top; } _mdl0Offset = header->_mdl0Offset; _stringOffset = header->_stringOffset; _userDataOffset = header->UserDataOffset(_initVersion); _shaderOffset = header->_shaderOffset; _dlOffset = header->DisplayListOffset(_initVersion); _furDataOffset = header->FurDataOffset(_initVersion); _matRefOffset = header->_matRefOffset; _pad = header->_pad; _dataLen = header->_dataLen; _numTextures = header->_numTexGens; _numLights = header->_numLightChans; _usageFlags = new Bin32(header->_usageFlags); _indirectMethod1 = header->_indirectMethod1; _indirectMethod2 = header->_indirectMethod2; _indirectMethod3 = header->_indirectMethod3; _indirectMethod4 = header->_indirectMethod4; _normMapRefLight1 = header->_normMapRefLight1; _normMapRefLight2 = header->_normMapRefLight2; _normMapRefLight3 = header->_normMapRefLight3; _normMapRefLight4 = header->_normMapRefLight4; _ssc = header->_activeTEVStages; _clip = header->_numIndTexStages; _transp = header->_enableAlphaTest; _lSet = header->_lightSet; _fSet = header->_fogSet; _cull = (CullMode)(int)header->_cull; if ((-header->_mdl0Offset + (int)header->DisplayListOffset(_initVersion)) % 0x20 != 0) { Model._errors.Add("Material " + Index + " has an improper align offset."); SignalPropertyChange(); } mode = header->DisplayLists(_initVersion); _alphaFunc = mode->AlphaFunction; _zMode = mode->ZMode; _blendMode = mode->BlendMode; _constantAlpha = mode->ConstantAlpha; _tevColorBlock = *header->TevColorBlock(_initVersion); _tevKonstBlock = *header->TevKonstBlock(_initVersion); _indMtx = *header->IndMtxBlock(_initVersion); MDL0TexSRTData* TexMatrices = header->TexMatrices(_initVersion); _layerFlags = TexMatrices->_layerFlags; _texMtxFlags = TexMatrices->_mtxFlags; MDL0MaterialLighting* Light = header->Light(_initVersion); (_chan1 = Light->Channel1)._parent = this; (_chan2 = Light->Channel2)._parent = this; c1 = CReg2Color; c2 = CReg2Color; c3 = CReg2Color; k1 = KReg0Color; k2 = KReg1Color; k3 = KReg2Color; k3 = KReg3Color; clr1 = C1MaterialColor; clr2 = C2MaterialColor; amb1 = C1AmbientColor; amb2 = C2AmbientColor; (_userEntries = new UserDataCollection()).Read(header->UserData(_initVersion)); return true; }