protected internal override void PostProcess(VoidPtr bresAddress, VoidPtr dataAddress, int dataLength, StringTable stringTable) { base.PostProcess(bresAddress, dataAddress, dataLength, stringTable); ResourceGroup *group; if (_version == 5) { SCN0v5 *header = (SCN0v5 *)dataAddress; header->ResourceStringAddress = stringTable[Name] + 4; if (!String.IsNullOrEmpty(_originalPath)) { header->OrigPathAddress = stringTable[_originalPath] + 4; } group = header->Group; } else { SCN0v4 *header = (SCN0v4 *)dataAddress; header->ResourceStringAddress = stringTable[Name] + 4; if (!String.IsNullOrEmpty(_originalPath)) { header->OrigPathAddress = stringTable[_originalPath] + 4; } group = header->Group; } group->_first = new ResourceEntry(0xFFFF, 0, 0, 0, 0); ResourceEntry *rEntry = group->First; int index = 1; int[] indices = new int[] { -1, -1, -1, -1, -1 }; foreach (SCN0GroupNode g in Children) { indices[(int)g._type] = g.Index; } VoidPtr addr = dataAddress; for (int i = 0; i < 5; i++) { SCN0GroupNode n = indices[i] >= 0 ? Children[indices[i]] as SCN0GroupNode : null; if (n != null) { addr = (VoidPtr)group + (rEntry++)->_dataOffset; ResourceEntry.Build(group, index++, addr, (BRESString *)stringTable[n.Name]); n.PostProcess(dataAddress, addr, stringTable); } } if (_version == 5) { _userEntries.PostProcess(((SCN0v5 *)addr)->UserData, stringTable); } }
public override bool OnInitialize() { base.OnInitialize(); if (_version == 5) { SCN0v5 *header = Header5; if ((_name == null) && (header->_stringOffset != 0)) { _name = header->ResourceString; } _numFrames = header->_frameCount; _specLights = header->_specLightCount; _loop = header->_loop != 0; _lightsets = header->_lightSetCount; _amblights = header->_ambientCount; _lights = header->_lightCount; _fogs = header->_fogCount; _cameras = header->_cameraCount; if (header->_origPathOffset > 0) { _originalPath = header->OrigPath; } (_userEntries = new UserDataCollection()).Read(header->UserData); return(header->Group->_numEntries > 0); } else { SCN0v4 *header = Header4; if ((_name == null) && (header->_stringOffset != 0)) { _name = header->ResourceString; } _numFrames = header->_frameCount; _specLights = header->_specLightCount; _loop = header->_loop != 0; _lightsets = header->_lightSetCount; _amblights = header->_ambientCount; _lights = header->_lightCount; _fogs = header->_fogCount; _cameras = header->_cameraCount; if (header->_origPathOffset > 0) { _originalPath = header->OrigPath; } return(header->Group->_numEntries > 0); } }
public override void OnRebuild(VoidPtr address, int length, bool force) { //Create data lengths for each group //group, lightset, ambient, light, fog, camera int[] lengths = new int[6]; //Create entry counts for each group //lightset, ambient, light, fog, camera short[] counts = new short[5]; //Create addresses for all data sections //group, entry, key, color, vis VoidPtr[] dataAddrs = new VoidPtr[5]; //Write header and retrieve main resource group ResourceGroup *group; if (_version == 5) { SCN0v5 *header = (SCN0v5 *)address; header->_origPathOffset = 0; header->_frameCount = (ushort)_numFrames; header->_specLightCount = (ushort)_specLights; header->_loop = _loop ? 1 : 0; header->_pad = 0; header->_dataOffset = SCN0v5.Size; group = header->Group; } else { SCN0v4 *header = (SCN0v4 *)address; header->_origPathOffset = 0; header->_frameCount = (ushort)_numFrames; header->_specLightCount = (ushort)_specLights; header->_loop = _loop ? 1 : 0; header->_pad = 0; header->_dataOffset = SCN0v4.Size; group = header->Group; } //Create resource group *group = new ResourceGroup(Children.Count); lengths[0] = group->_totalSize; //Get pointer to main resource entry buffer ResourceEntry *entry = group->First; //Get pointer to resource groups for each child group dataAddrs[0] = group->EndAddress; //Get pointer to the address for headers for (int i = 0; i < 4; i++) { dataAddrs[i + 1] = dataAddrs[i]; foreach (SCN0GroupNode g in Children) { if (i == 0) { dataAddrs[i + 1] += g._dataLengths[i]; } else { foreach (SCN0EntryNode e in g.Children) { dataAddrs[i + 1] += (i == 1 ? e._calcSize : e._dataLengths[i - 2]); } } } } //Use an index array to remap and write groups in proper order. int[] indices = new int[] { -1, -1, -1, -1, -1 }; //Loop through groups and set index, length and count foreach (SCN0GroupNode g in Children) { int i = (int)g._type; indices[i] = g.Index; lengths[i + 1] = g._dataLengths[1]; counts[i] = (short)g.Children.Count; } //Now loop through indices to get each group and write it for (int i = 0; i < 5; i++) { //Make sure the group exists SCN0GroupNode g = indices[i] >= 0 ? Children[indices[i]] as SCN0GroupNode : null; if (g != null) { //Set offset to group in main resource group (entry++)->_dataOffset = (int)dataAddrs[0] - (int)group; //Set addresses for rebuild for (int x = 0; x < 4; x++) { g._addrs[x] = dataAddrs[x + 1]; } //Rebuild focusing on the resource group g.Rebuild(dataAddrs[0], g._dataLengths[0], true); //Increment addresses lengths[0] += g._dataLengths[0]; for (int x = 0; x < 5; x++) { dataAddrs[x] += g._dataLengths[x]; } } } //Set header values if (_version == 5) { SCN0v5 *header = (SCN0v5 *)address; header->_lightSetCount = counts[0]; header->_ambientCount = counts[1]; header->_lightCount = counts[2]; header->_fogCount = counts[3]; header->_cameraCount = counts[4]; header->Set(lengths[0], lengths[1], lengths[2], lengths[3], lengths[4], lengths[5]); if (_userEntries.Count > 0) { _userEntries.Write(header->UserData = dataAddrs[4]); } } else { SCN0v4 *header = (SCN0v4 *)address; header->_lightSetCount = counts[0]; header->_ambientCount = counts[1]; header->_lightCount = counts[2]; header->_fogCount = counts[3]; header->_cameraCount = counts[4]; header->Set(lengths[0], lengths[1], lengths[2], lengths[3], lengths[4], lengths[5]); } }
public override void OnRebuild(VoidPtr address, int length, bool force) { int GroupLen = 0, LightSetLen = 0, AmbLightSetLen = 0, LightLen = 0, FogLen = 0, CameraLen = 0; _header = address; ResourceGroup *group; if (_version == 5) { SCN0v5 *header = (SCN0v5 *)address; header->_origPathOffset = _origPathOffset; header->_frameCount = (short)_frameCount; header->_specLightCount = (short)_specLights; header->_loop = _loop; header->_pad = 0; header->_dataOffset = SCN0v5.Size; group = header->Group; } else { SCN0v4 *header = (SCN0v4 *)address; header->_origPathOffset = _origPathOffset; header->_frameCount = (short)_frameCount; header->_specLightCount = (short)_specLights; header->_loop = _loop; header->_pad = 0; header->_dataOffset = SCN0v4.Size; group = header->Group; } *group = new ResourceGroup(Children.Count); GroupLen = group->_totalSize; ResourceEntry *entry = group->First; VoidPtr groupAddress = group->EndAddress; VoidPtr entryAddress = groupAddress; foreach (SCN0GroupNode g in Children) { entryAddress += g._groupLen; } VoidPtr keyframeAddress = entryAddress; foreach (SCN0GroupNode g in Children) { foreach (SCN0EntryNode e in g.Children) { keyframeAddress += e._length; } } VoidPtr lightArrayAddress = keyframeAddress; foreach (SCN0GroupNode g in Children) { foreach (SCN0EntryNode e in g.Children) { lightArrayAddress += e._keyLen; } } VoidPtr visibilityAddress = lightArrayAddress; foreach (SCN0GroupNode g in Children) { foreach (SCN0EntryNode e in g.Children) { visibilityAddress += e._lightLen; } } short _lightSetCount = 0, _ambientCount = 0, _lightCount = 0, _fogCount = 0, _cameraCount = 0; int[] indices = new int[] { -1, -1, -1, -1, -1 }; foreach (SCN0GroupNode g in Children) { if (g._name == "LightSet(NW4R)") { indices[0] = g.Index; LightSetLen = g._entryLen; _lightSetCount = (short)g.Children.Count; } else if (g._name == "AmbLights(NW4R)") { indices[1] = g.Index; AmbLightSetLen = g._entryLen; _ambientCount = (short)g.Children.Count; } else if (g._name == "Lights(NW4R)") { indices[2] = g.Index; LightLen = g._entryLen; _lightCount = (short)g.Children.Count; } else if (g._name == "Fogs(NW4R)") { indices[3] = g.Index; FogLen = g._entryLen; _fogCount = (short)g.Children.Count; } else if (g._name == "Cameras(NW4R)") { indices[4] = g.Index; CameraLen = g._entryLen; _cameraCount = (short)g.Children.Count; } } for (int i = 0; i < 5; i++) { SCN0GroupNode g = indices[i] >= 0 ? Children[indices[i]] as SCN0GroupNode : null; if (g != null) { (entry++)->_dataOffset = (int)groupAddress - (int)group; g._dataAddr = entryAddress; g.keyframeAddress = keyframeAddress; g.lightArrayAddress = lightArrayAddress; g.visibilityAddress = visibilityAddress; g.Rebuild(groupAddress, g._groupLen, true); groupAddress += g._groupLen; GroupLen += g._groupLen; entryAddress += g._entryLen; keyframeAddress += g.keyLen; lightArrayAddress += g.lightLen; visibilityAddress += g.visLen; } } if (_version == 5) { SCN0v5 *header = (SCN0v5 *)address; header->_lightSetCount = _lightSetCount; header->_ambientCount = _ambientCount; header->_lightCount = _lightCount; header->_fogCount = _fogCount; header->_cameraCount = _cameraCount; header->Set(GroupLen, LightSetLen, AmbLightSetLen, LightLen, FogLen, CameraLen); if (_userEntries.Count > 0) { _userEntries.Write(header->UserData = lightArrayAddress); } } else { SCN0v4 *header = (SCN0v4 *)address; header->_lightSetCount = _lightSetCount; header->_ambientCount = _ambientCount; header->_lightCount = _lightCount; header->_fogCount = _fogCount; header->_cameraCount = _cameraCount; header->Set(GroupLen, LightSetLen, AmbLightSetLen, LightLen, FogLen, CameraLen); } }