public virtual FileMap EncodeTEX0Texture(Bitmap src, int mipLevels) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels) + 0x40); try { //Build TEX header TEX0v1 *header = (TEX0v1 *)fileView.Address; * header = new TEX0v1(w, h, RawFormat, mipLevels); int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) for (int i = 1; i <= mipLevels; i++) { EncodeLevel(header->PixelData, dib, src, dStep, sStep, i); } return(fileView); } catch (Exception x) { MessageBox.Show(x.ToString()); fileView.Dispose(); return(null); } }
public unsafe virtual void ReplaceRaw(VoidPtr address, int length) { FileMap map = FileMap.FromTempFile(length); Memory.Move(map.Address, address, (uint)length); ReplaceRaw(map); }
public virtual void Rebuild(bool force) { if (!IsDirty && !force) { return; } //Get uncompressed size int size = OnCalculateSize(force); //Create temp map FileMap uncompMap = FileMap.FromTempFile(size); //Rebuild node (uncompressed) Rebuild(uncompMap.Address, size, force); _replSrc.Map = _replUncompSrc.Map = uncompMap; //If compressed, compress resulting data. if (_compression != CompressionType.None) { //Compress node to temp file FileStream stream = new FileStream(Path.GetTempFileName(), FileMode.Open, FileAccess.ReadWrite, FileShare.None, 0x8, FileOptions.DeleteOnClose | FileOptions.SequentialScan); try { Compressor.Compact(_compression, uncompMap.Address, uncompMap.Length, stream); _replSrc = new DataSource(FileMap.FromStreamInternal(stream, FileMapProtect.Read, 0, (int)stream.Length), _compression); } catch (Exception x) { stream.Dispose(); throw x; } } }
public static unsafe ResourceNode FromSource(ResourceNode parent, DataSource source) { ResourceNode n = null; if ((n = GetRaw(source)) != null) { n.Initialize(parent, source); } else { //Check for compression? if (Compressor.IsDataCompressed(source.Address, source.Length)) { if ((*(uint *)source.Address) == YAZ0.Tag) { YAZ0 *cmpr = (YAZ0 *)source.Address; try { //Expand the whole resource and initialize FileMap map = FileMap.FromTempFile((int)cmpr->_unCompDataLen); Compressor.Expand(cmpr, map.Address, map.Length); source.Compression = CompressionType.RunLength; //Check for a match if ((n = GetRaw(new DataSource(map.Address, map.Length))) != null) { n.Initialize(parent, source, new DataSource(map)); } } catch (InvalidCompressionException e) { MessageBox.Show(e.ToString()); } } else { CompressionHeader *cmpr = (CompressionHeader *)source.Address; if (Compressor.Supports(cmpr->Algorithm)) { try { //Expand a portion of the data byte *buffer = stackalloc byte[CompressBufferLen]; Compressor.Expand(cmpr, buffer, CompressBufferLen); //Check for a match if ((n = GetRaw(new DataSource(buffer, CompressBufferLen))) != null) { //Expand the whole resource and initialize FileMap map = FileMap.FromTempFile(cmpr->ExpandedSize); Compressor.Expand(cmpr, map.Address, map.Length); source.Compression = cmpr->Algorithm; n.Initialize(parent, source, new DataSource(map)); } } catch (InvalidCompressionException e) { MessageBox.Show(e.ToString()); } } } } } return(n); }
public void ConvertToV2() { int size = 0x08 + Entries.Count * 0x10; string path = _workingSource.Map.FilePath; _workingSource.Close(); _workingSource = new DataSource(FileMap.FromTempFile(size)); VoidPtr addr = _workingSource.Address; *(uint *)addr = 0x0002666f; *(int *)(addr + 4) = Entries.Count; addr += 0x08; for (int i = 0; i < Entries.Count; i++) { LSEntryObject lsobj = Entries.Values[i]; LSEntry_v2 * entry = (LSEntry_v2 *)(addr + (i * 0x10)); *entry = new LSEntry_v2() { _crc = lsobj.FileNameCRC, _start = lsobj.DTOffset, _size = lsobj.Size, _dtIndex = lsobj.DTIndex, _padlen = lsobj.PaddingLength }; } _workingSource.Export(path); }
public void CreateEntry() { FileMap tempFile = FileMap.FromTempFile(sizeof(ClassicStageBlock)); // Is this the right way to add a new child node? var node = new ClassicStageBlockNode(); node.Initialize(this, tempFile); AddChild(node, true); }
/// <summary> /// Creates a ResourceNode from a temporary file using FileMap.FromTempFile. The file will be deleted when the underlying FileMap's stream is closed. /// </summary> public static ResourceNode MakeTempNode(string path) { byte[] data = File.ReadAllBytes(path); FileMap map = FileMap.FromTempFile(data.Length); Console.WriteLine(path + " -> FromTempFile -> " + map.FilePath); Marshal.Copy(data, 0, map.Address, data.Length); return(NodeFactory.FromSource(null, new DataSource(map))); }
public unsafe FileMap ToFileMap() { FileMap map = FileMap.FromTempFile(_data.Length); byte * ptr = (byte *)map.Address; for (int i = 0; i < _data.Length; i++) { ptr[i] = _data[i]; } return(map); }
public unsafe virtual void ReplaceRaw(FileMap map) { if (_children != null) { foreach (ResourceNode node in _children) { node.Dispose(); } _children.Clear(); _children = null; } _replUncompSrc.Close(); _replSrc.Close(); if (Compressor.IsDataCompressed(map.Address, map.Length)) { CompressionHeader *cmpr = (CompressionHeader *)map.Address; _compression = cmpr->Algorithm; if (Compressor.Supports(cmpr->Algorithm)) { FileMap uncompMap = FileMap.FromTempFile(cmpr->ExpandedSize); Compressor.Expand(cmpr, uncompMap.Address, uncompMap.Length); _replSrc = new DataSource(map, cmpr->Algorithm); _replUncompSrc = new DataSource(uncompMap); } else { _replSrc = _replUncompSrc = new DataSource(map); } } else { _compression = CompressionType.None; _replSrc = _replUncompSrc = new DataSource(map); } _replaced = true; if (!OnInitialize()) { _children = new List <ResourceNode>(); } _replaced = false; _changed = false; if (Replaced != null) { Replaced(this); } }
/// <summary> /// Applies changes. /// </summary> public void Rebuild() { FileMap temp = FileMap.FromTempFile(Size); // Write changes to the new filemap. OnRebuild(temp.Address, temp.Length); // Close backing source. _replSource.Close(); // set backing source to new source from temp map. _replSource = new DataSource(temp.Address, temp.Length) { Map = temp }; // Set backing source's map to the temp map. }
public virtual FileMap EncodeTPLTexture(Bitmap src, int mipLevels) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels) + TPLTextureHeader.Size); try { //Build TPL header TPLTextureHeader *tex = (TPLTextureHeader *)fileView.Address; tex->_wrapS = 0; tex->_wrapT = 0; tex->_minFilter = 1; tex->_magFilter = 1; tex->_minLOD = 0; tex->_maxLOD = (byte)(mipLevels - 1); tex->PixelFormat = RawFormat; tex->_width = (ushort)w; tex->_height = (ushort)h; tex->_data = TPLTextureHeader.Size; int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; VoidPtr baseAddr = fileView.Address; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) { for (int i = 1; i <= mipLevels; i++) { EncodeLevel(baseAddr + tex->_data, dib, src, dStep, sStep, i); } } return(fileView); } catch (Exception x) { MessageBox.Show(x.ToString()); fileView.Dispose(); return(null); } }
public static FileMap EncodePalette(ColorPalette pal, WiiPaletteFormat format) { FileMap fileView = FileMap.FromTempFile((pal.Entries.Length * 2)); try { EncodePalette(fileView.Address, pal, format); return(fileView); } catch (Exception x) { fileView.Dispose(); throw; //MessageBox.Show(x.ToString()); //fileView.Dispose(); //return null; } }
public static FileMap TryExpand(ref DataSource source, bool doTest = true) { FileMap decompressedMap = null; CompressionType algorithm = GetAlgorithm(source); if (Supports(source.Compression = algorithm)) { try { if (doTest && !Test(algorithm, source.Address)) { return(null); } uint len = 0; if (algorithm == CompressionType.RunLengthYAZ0) { len = *(buint *)(source.Address + 4); decompressedMap = FileMap.FromTempFile((int)len); Expand((YAZ0 *)source.Address, decompressedMap.Address, decompressedMap.Length); } else if (algorithm == CompressionType.RunLengthYAY0) { len = *(buint *)(source.Address + 4); decompressedMap = FileMap.FromTempFile((int)len); Expand((YAY0 *)source.Address, decompressedMap.Address, decompressedMap.Length); } else { CompressionHeader *hdr = (CompressionHeader *)source.Address; len = hdr->ExpandedSize; decompressedMap = FileMap.FromTempFile((int)len); Expand(hdr, decompressedMap.Address, decompressedMap.Length); } } catch (InvalidCompressionException e) { MessageBox.Show(e.ToString()); } } return(decompressedMap); }
public static FileMap EncodePLT0Palette(ColorPalette pal, WiiPaletteFormat format) { FileMap fileView = FileMap.FromTempFile((pal.Entries.Length * 2) + 0x40); try { PLT0v1 *header = (PLT0v1 *)fileView.Address; * header = new PLT0v1(pal.Entries.Length, format); EncodePalette(fileView.Address + 0x40, pal, format); return(fileView); } catch (Exception x) { fileView.Dispose(); throw; //MessageBox.Show(x.ToString()); //fileView.Dispose(); //return null; } }
public static FileMap EncodeTPLPalette(ColorPalette pal, WiiPaletteFormat format) { FileMap fileView = FileMap.FromTempFile((pal.Entries.Length * 2) + 0xC); try { TPLPaletteHeader *header = (TPLPaletteHeader *)fileView.Address; header->_format = (uint)format; header->_numEntries = (ushort)pal.Entries.Length; header->_data = 0xC; EncodePalette(fileView.Address + 0xC, pal, format); return(fileView); } catch (Exception x) { fileView.Dispose(); throw; //MessageBox.Show(x.ToString()); //fileView.Dispose(); //return null; } }
public virtual FileMap EncodeTexture(Bitmap src, int mipLevels) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; //int aw = w.Align(bw), ah = h.Align(bh); PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; //int fileSize = GetMipOffset(w, h, mipLevels + 1) + 0x40; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels, false)); //FileMap fileView = FileMap.FromTempFile(fileSize); try { //Build TEX header TEX0 *header = (TEX0 *)fileView.Address; * header = new TEX0(w, h, RawFormat, mipLevels); int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; VoidPtr baseAddr = header->PixelData; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) for (int i = 1; i <= mipLevels; i++) { EncodeLevel(header, dib, src, dStep, sStep, i); } return(fileView); } catch (Exception x) { //MessageBox.Show(x.ToString()); fileView.Dispose(); return(null); } }
public static unsafe ResourceNode FromSource(ResourceNode parent, DataSource source) { ResourceNode n = null; if ((n = GetRaw(source)) != null) { n.Initialize(parent, source); } else { //Check for compression? if (Compressor.IsDataCompressed(source.Address, source.Length)) { CompressionHeader *cmpr = (CompressionHeader *)source.Address; try { //Expand a portion of the data byte *buffer = stackalloc byte[CompressBufferLen]; Compressor.Expand(cmpr, buffer, CompressBufferLen); //Check for a match if ((n = GetRaw(new DataSource(buffer, CompressBufferLen))) != null) { //Expand the whole resource and initialize FileMap map = FileMap.FromTempFile(cmpr->ExpandedSize); Compressor.Expand(cmpr, map.Address, map.Length); source.Compression = cmpr->Algorithm; n.Initialize(parent, source, new DataSource(map)); } } catch (InvalidCompressionException) { } } } return(n); }
public static unsafe FileMap Encode(IAudioStream stream, IProgressTracker progress) { int tmp; bool looped = stream.IsLooping; int channels = stream.Channels; int samples; int blocks; int sampleRate = stream.Frequency; int lbSamples, lbSize, lbTotal; int loopPadding, loopStart, totalSamples; short *tPtr; if (looped) { loopStart = stream.LoopStartSample; samples = stream.LoopEndSample; //Set sample size to end sample. That way the audio gets cut off when encoding. //If loop point doesn't land on a block, pad the stream so that it does. if ((tmp = loopStart % 0x3800) != 0) { loopPadding = 0x3800 - tmp; loopStart += loopPadding; } else { loopPadding = 0; } totalSamples = loopPadding + samples; } else { loopPadding = loopStart = 0; totalSamples = samples = stream.Samples; } if (progress != null) { progress.Begin(0, totalSamples * channels * 3, 0); } blocks = (totalSamples + 0x37FF) / 0x3800; //Initialize stream info if ((tmp = totalSamples % 0x3800) != 0) { lbSamples = tmp; lbSize = (lbSamples + 13) / 14 * 8; lbTotal = lbSize.Align(0x20); } else { lbSamples = 0x3800; lbTotal = lbSize = 0x2000; } //Get section sizes int rstmSize = 0x40; int headSize = (0x68 + (channels * 0x40)).Align(0x20); int adpcSize = ((blocks - 1) * 4 * channels + 0x10).Align(0x20); int dataSize = ((blocks - 1) * 0x2000 + lbTotal) * channels + 0x20; //Create file map FileMap map = FileMap.FromTempFile(rstmSize + headSize + adpcSize + dataSize); //Get section pointers RSTMHeader * rstm = (RSTMHeader *)map.Address; HEADHeader * head = (HEADHeader *)((int)rstm + rstmSize); ADPCHeader * adpc = (ADPCHeader *)((int)head + headSize); RSTMDATAHeader *data = (RSTMDATAHeader *)((int)adpc + adpcSize); //Initialize sections rstm->Set(headSize, adpcSize, dataSize); head->Set(headSize, channels); adpc->Set(adpcSize); data->Set(dataSize); //Set HEAD data StrmDataInfo *part1 = head->Part1; part1->_format = new AudioFormatInfo(2, (byte)(looped ? 1 : 0), (byte)channels, 0); part1->_sampleRate = (ushort)sampleRate; part1->_blockHeaderOffset = 0; part1->_loopStartSample = loopStart; part1->_numSamples = totalSamples; part1->_dataOffset = rstmSize + headSize + adpcSize + 0x20; part1->_numBlocks = blocks; part1->_blockSize = 0x2000; part1->_samplesPerBlock = 0x3800; part1->_lastBlockSize = lbSize; part1->_lastBlockSamples = lbSamples; part1->_lastBlockTotal = lbTotal; part1->_dataInterval = 0x3800; part1->_bitsPerSample = 4; //Create one ADPCMInfo for each channel int * adpcData = stackalloc int[channels]; ADPCMInfo **pAdpcm = (ADPCMInfo **)adpcData; for (int i = 0; i < channels; i++) { *(pAdpcm[i] = head->GetChannelInfo(i)) = new ADPCMInfo() { _pad = 0 } } ; //Create buffer for each channel int * bufferData = stackalloc int[channels]; short **channelBuffers = (short **)bufferData; int bufferSamples = totalSamples + 2; //Add two samples for initial yn values for (int i = 0; i < channels; i++) { channelBuffers[i] = tPtr = (short *)Marshal.AllocHGlobal(bufferSamples * 2); //Two bytes per sample //Zero padding samples and initial yn values for (int x = 0; x < (loopPadding + 2); x++) { *tPtr++ = 0; } } //Fill buffers stream.SamplePosition = 0; short *sampleBuffer = stackalloc short[channels]; for (int i = 2; i < bufferSamples; i++) { if (stream.SamplePosition == stream.LoopEndSample && looped) { stream.SamplePosition = stream.LoopStartSample; } stream.ReadSamples(sampleBuffer, 1); for (int x = 0; x < channels; x++) { channelBuffers[x][i] = sampleBuffer[x]; } } //Calculate coefs for (int i = 0; i < channels; i++) { AudioConverter.CalcCoefs(channelBuffers[i] + 2, totalSamples, (short *)pAdpcm[i], progress); } //Encode blocks byte * dPtr = (byte *)data->Data; bshort *pyn = (bshort *)adpc->Data; for (int sIndex = 0, bIndex = 1; sIndex < totalSamples; sIndex += 0x3800, bIndex++) { int blockSamples = Math.Min(totalSamples - sIndex, 0x3800); for (int x = 0; x < channels; x++) { short *sPtr = channelBuffers[x] + sIndex; //Set block yn values if (bIndex != blocks) { *pyn++ = sPtr[0x3801]; *pyn++ = sPtr[0x3800]; } //Encode block (include yn in sPtr) AudioConverter.EncodeBlock(sPtr, blockSamples, dPtr, (short *)pAdpcm[x]); //Set initial ps if (bIndex == 1) { pAdpcm[x]->_ps = *dPtr; } //Advance output pointer if (bIndex == blocks) { //Fill remaining dPtr += lbSize; for (int i = lbSize; i < lbTotal; i++) { *dPtr++ = 0; } } else { dPtr += 0x2000; } } if (progress != null) { if ((sIndex % 0x3800) == 0) { progress.Update(progress.CurrentValue + (0x7000 * channels)); } } } //Reverse coefs for (int i = 0; i < channels; i++) { short *p = pAdpcm[i]->_coefs; for (int x = 0; x < 16; x++, p++) { *p = p->Reverse(); } } //Write loop states if (looped) { //Can't we just use block states? int loopBlock = loopStart / 0x3800; int loopChunk = (loopStart - (loopBlock * 0x3800)) / 14; dPtr = (byte *)data->Data + (loopBlock * 0x2000 * channels) + (loopChunk * 8); tmp = (loopBlock == blocks - 1) ? lbTotal : 0x2000; for (int i = 0; i < channels; i++, dPtr += tmp) { //Use adjusted samples for yn values tPtr = channelBuffers[i] + loopStart; pAdpcm[i]->_lps = *dPtr; pAdpcm[i]->_lyn2 = *tPtr++; pAdpcm[i]->_lyn1 = *tPtr; } } //Free memory for (int i = 0; i < channels; i++) { Marshal.FreeHGlobal((IntPtr)channelBuffers[i]); } if (progress != null) { progress.Finish(); } return(map); } }
public static unsafe FileMap Encode(IAudioStream stream, IProgressTracker progress) { int tmp; bool looped = stream.IsLooping; int channels = stream.Channels; int samples; int blocks; int sampleRate = stream.Frequency; int lbSamples, lbSize, lbTotal; int /*loopPadding, */ loopStart, totalSamples; short *tPtr; int blockLen, samplesPerBlock; if (looped) { loopStart = stream.LoopStartSample; samples = stream.LoopEndSample; //Set sample size to end sample. That way the audio gets cut off when encoding. blockLen = (samples.Align(14) / 14 * 8); samplesPerBlock = blockLen / 8 * 14; //If loop point doesn't land on a block, pad the stream so that it does. //if ((tmp = loopStart % samplesPerBlock) != 0) //{ // loopPadding = samplesPerBlock - tmp; // loopStart += loopPadding; //} //else // loopPadding = 0; totalSamples = /*loopPadding + */ samples; } else { //loopPadding = 0; loopStart = 0; totalSamples = samples = stream.Samples; blockLen = (samples.Align(14) / 14 * 8); samplesPerBlock = blockLen / 8 * 14; } if (progress != null) { progress.Begin(0, totalSamples * channels * 3, 0); } blocks = (totalSamples + (samplesPerBlock - 1)) / samplesPerBlock; //Initialize stream info if ((tmp = totalSamples % samplesPerBlock) != 0) { lbSamples = tmp; lbSize = (lbSamples + 13) / 14 * 8; lbTotal = lbSize.Align(0x20); } else { lbSamples = samplesPerBlock; lbTotal = lbSize = blockLen; } //Get section sizes int headerSize = RWAV.Size, infoSize = 8, waveSize = 0x1C, tableSize = channels * 4, channelSize = channels * 0x1C, adpcmInfoSize = channels * 0x30, entrySize = (infoSize + waveSize + tableSize + channelSize + adpcmInfoSize).Align(0x20) - 8, dataSize = (((blocks - 1) * blockLen + lbTotal) * channels) + 8; //Create file map FileMap map = FileMap.FromTempFile(headerSize + entrySize + 8 + dataSize); //Get section pointers RWAV *header = (RWAV *)map.Address; header->_header._tag = RWAV.Tag; header->_header.Endian = Endian.Big; header->_header._version = 0x102; header->_header._length = map.Length; header->_header._firstOffset = 0x20; header->_header._numEntries = 2; header->_infoOffset = 0x20; header->_infoLength = entrySize + 8; header->_dataOffset = 0x20 + entrySize + 8; header->_dataLength = dataSize; RWAVInfo *infoBlock = header->Info; infoBlock->_header._tag = RWAVInfo.Tag; infoBlock->_header._length = entrySize + 8; WaveInfo *wave = &infoBlock->_info; wave->_format = new AudioFormatInfo(2, (byte)(looped ? 1 : 0), (byte)channels, 0); wave->_sampleRate = (ushort)sampleRate; wave->_channelInfoTableOffset = 0x1C; wave->_dataLocation = (uint)(header->Data->Data - map.Address); wave->LoopSample = loopStart; wave->NumSamples = totalSamples; RWAVData *dataBlock = header->Data; dataBlock->_header._tag = RWAVData.Tag; dataBlock->_header._length = dataSize; //Create one ChannelInfo for each channel buint * table = (buint *)((VoidPtr)wave + 0x1C); ChannelInfo *channelInfo = (ChannelInfo *)((VoidPtr)wave + waveSize + tableSize); for (int i = 0; i < channels; i++) { table[i] = (uint)&channelInfo[i] - (uint)wave; channelInfo[i] = new ChannelInfo() { _volBackLeft = 1, _volBackRight = 1, _volFrontLeft = 1, _volFrontRight = 1, _adpcmInfoOffset = waveSize + tableSize + channelSize + i * 0x30 }; } //Create one ADPCMInfo for each channel int * adpcData = stackalloc int[channels]; ADPCMInfo **pAdpcm = (ADPCMInfo **)adpcData; for (int i = 0; i < channels; i++) { *(pAdpcm[i] = wave->GetADPCMInfo(i)) = new ADPCMInfo(); } //Create buffer for each channel int * bufferData = stackalloc int[channels]; short **channelBuffers = (short **)bufferData; int bufferSamples = totalSamples + 2; //Add two samples for initial yn values for (int i = 0; i < channels; i++) { channelBuffers[i] = tPtr = (short *)Marshal.AllocHGlobal(bufferSamples * 2); //Two bytes per sample //Zero padding samples and initial yn values //for (int x = 0; x < (loopPadding + 2); x++) // *tPtr++ = 0; } //Fill buffers stream.SamplePosition = 0; short *sampleBuffer = stackalloc short[channels]; for (int i = 2; i < bufferSamples; i++) { //if (stream.SamplePosition == stream.LoopEndSample && looped) // stream.SamplePosition = stream.LoopStartSample; stream.ReadSamples(sampleBuffer, 1); for (int x = 0; x < channels; x++) { channelBuffers[x][i] = sampleBuffer[x]; } } //Calculate coefs for (int i = 0; i < channels; i++) { AudioConverter.CalcCoefs(channelBuffers[i] + 2, totalSamples, (short *)pAdpcm[i], progress); } //Encode blocks byte *dPtr = (byte *)dataBlock->Data; for (int sIndex = 0, bIndex = 1; sIndex < totalSamples; sIndex += samplesPerBlock, bIndex++) { int blockSamples = Math.Min(totalSamples - sIndex, samplesPerBlock); for (int x = 0; x < channels; x++) { channelInfo[x]._channelDataOffset = (int)(dPtr - (byte *)dataBlock->Data); short *sPtr = channelBuffers[x] + sIndex; //Set block yn values if (bIndex != blocks) { pAdpcm[x]->_yn1 = sPtr[samplesPerBlock + 1]; pAdpcm[x]->_yn2 = sPtr[samplesPerBlock]; } //Encode block (include yn in sPtr) AudioConverter.EncodeBlock(sPtr, blockSamples, dPtr, (short *)pAdpcm[x]); //Set initial ps if (bIndex == 1) { pAdpcm[x]->_ps = *dPtr; } //Advance output pointer if (bIndex == blocks) { //Fill remaining dPtr += lbSize; for (int i = lbSize; i < lbTotal; i++) { *dPtr++ = 0; } } else { dPtr += blockLen; } } if (progress != null && (sIndex % samplesPerBlock) == 0) { progress.Update(progress.CurrentValue + (samplesPerBlock * 2 * channels)); } } //Reverse coefs for (int i = 0; i < channels; i++) { short *p = pAdpcm[i]->_coefs; for (int x = 0; x < 16; x++, p++) { *p = p->Reverse(); } } //Write loop states if (looped) { //Can't we just use block states? int loopBlock = loopStart / samplesPerBlock; int loopChunk = (loopStart - (loopBlock * samplesPerBlock)) / 14; dPtr = (byte *)dataBlock->Data + (loopBlock * blockLen * channels) + (loopChunk * 8); tmp = (loopBlock == blocks - 1) ? lbTotal : blockLen; for (int i = 0; i < channels; i++, dPtr += tmp) { //Use adjusted samples for yn values tPtr = channelBuffers[i] + loopStart; pAdpcm[i]->_lps = *dPtr; pAdpcm[i]->_lyn2 = *tPtr++; pAdpcm[i]->_lyn1 = *tPtr; } } //Free memory for (int i = 0; i < channels; i++) { Marshal.FreeHGlobal((IntPtr)channelBuffers[i]); } if (progress != null) { progress.Finish(); } return(map); }
//Parser commands must initialize the node before returning. public unsafe static ResourceNode FromFile(ResourceNode parent, string path) { ResourceNode node = null; FileMap map = FileMap.FromFile(path, FileMapProtect.Read); try { DataSource source = new DataSource(map); if (String.Equals(Path.GetExtension(path), ".mrg", StringComparison.OrdinalIgnoreCase) || String.Equals(Path.GetExtension(path), ".mrgc", StringComparison.OrdinalIgnoreCase)) { node = new MRGNode(); if (Compressor.IsDataCompressed(source.Address, source.Length)) { CompressionHeader *cmpr = (CompressionHeader *)source.Address; source.Compression = cmpr->Algorithm; if (Compressor.Supports(cmpr->Algorithm)) { try { //Expand the whole resource and initialize FileMap uncompMap = FileMap.FromTempFile(cmpr->ExpandedSize); Compressor.Expand(cmpr, uncompMap.Address, uncompMap.Length); node.Initialize(parent, source, new DataSource(uncompMap)); } catch (InvalidCompressionException e) { MessageBox.Show(e.ToString()); } } else { node.Initialize(parent, source); } } else { node.Initialize(parent, source); } } else if (String.Equals(Path.GetExtension(path), ".rel", StringComparison.OrdinalIgnoreCase)) { node = new RELNode(); node.Initialize(parent, map); } else if (String.Equals(Path.GetExtension(path), ".dol", StringComparison.OrdinalIgnoreCase)) { node = new DOLNode(); node.Initialize(parent, map); } else if ((node = FromSource(parent, source)) == null) { //if (Compressor.IsDataCompressed(source.Address, source.Length)) //{ // CompressionHeader* cmpr = (CompressionHeader*)source.Address; // if (!Compressor.Supports(cmpr->Algorithm)) // MessageBox.Show("File uses unsupported " + cmpr->Algorithm.ToString() + " compression."); //} } } finally { if (node == null) { map.Dispose(); } } return(node); }
public virtual FileMap EncodeREFTTexture(Bitmap src, int mipLevels, WiiPaletteFormat format, bool usePalette) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; //int aw = w.Align(bw), ah = h.Align(bh); ColorPalette pal = src.Palette; PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; //int fileSize = GetMipOffset(w, h, mipLevels + 1) + 0x20; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels, true) + (usePalette ? (pal.Entries.Length * 2) : 0)); //FileMap fileView = FileMap.FromTempFile(fileSize); try { //Build REFT image header REFTData *header = (REFTData *)fileView.Address; * header = new REFTData((ushort)w, (ushort)h, (byte)RawFormat); header->_imagelen = (uint)fileView.Length - 0x20; int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; VoidPtr baseAddr = (byte *)header + 0x20; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) for (int i = 1; i <= mipLevels; i++) { EncodeLevel(baseAddr, dib, src, dStep, sStep, i); } if (usePalette) { int count = pal.Entries.Length; header->_colorCount = (ushort)count; header->_pltFormat = (byte)format; switch (format) { case WiiPaletteFormat.IA8: { IA8Pixel *dPtr = (IA8Pixel *)header->PaletteData; for (int i = 0; i < count; i++) { dPtr[i] = (IA8Pixel)pal.Entries[i]; } break; } case WiiPaletteFormat.RGB565: { wRGB565Pixel *dPtr = (wRGB565Pixel *)header->PaletteData; for (int i = 0; i < count; i++) { dPtr[i] = (wRGB565Pixel)pal.Entries[i]; } break; } case WiiPaletteFormat.RGB5A3: { wRGB5A3Pixel *dPtr = (wRGB5A3Pixel *)header->PaletteData; for (int i = 0; i < count; i++) { dPtr[i] = (wRGB5A3Pixel)pal.Entries[i]; } break; } } } return(fileView); } catch (Exception x) { //MessageBox.Show(x.ToString()); fileView.Dispose(); return(null); } }
public static unsafe FileMap Encode(IAudioStream stream, IProgressTracker progress, WaveEncoding encoding = WaveEncoding.ADPCM) #endif { int tmp; bool looped = stream.IsLooping; int channels = stream.Channels; int samples; int blocks; int sampleRate = stream.Frequency; int lbSamples, lbSize, lbTotal; int loopPadding, loopStart, totalSamples; short *tPtr; int samplesPerBlock = encoding == WaveEncoding.ADPCM ? 0x3800 : encoding == WaveEncoding.PCM16 ? 0x1000 : 0; if (samplesPerBlock == 0) { throw new ArgumentException("Encoding must be ADPCM or PCM16"); } if (looped) { loopStart = stream.LoopStartSample; samples = stream.LoopEndSample; //Set sample size to end sample. That way the audio gets cut off when encoding. //If loop point doesn't land on a block, pad the stream so that it does. if ((tmp = loopStart % samplesPerBlock) != 0) { loopPadding = samplesPerBlock - tmp; loopStart += loopPadding; } else { loopPadding = 0; } totalSamples = loopPadding + samples; } else { loopPadding = loopStart = 0; totalSamples = samples = stream.Samples; } if (progress != null) { progress.Begin(0, totalSamples * channels * 3, 0); } blocks = (totalSamples + samplesPerBlock - 1) / samplesPerBlock; //Initialize stream info if ((tmp = totalSamples % samplesPerBlock) != 0) { lbSamples = tmp; if (encoding == WaveEncoding.ADPCM) { lbSize = (lbSamples + 13) / 14 * 8; } else if (encoding == WaveEncoding.PCM16) { lbTotal = lbSize = lbSamples * 2; } else if (encoding == WaveEncoding.PCM8) { lbTotal = lbSize = lbSamples; } else { throw new NotImplementedException(); } lbTotal = lbSize.Align(0x20); } else { lbSamples = samplesPerBlock; lbTotal = lbSize = 0x2000; } //Get section sizes int rstmSize = 0x40; int headSize = (0x68 + (channels * (encoding == WaveEncoding.ADPCM ? 0x40 : 0x10))).Align(0x20); int adpcSize = encoding == WaveEncoding.ADPCM ? ((blocks - 1) * 4 * channels + 0x10).Align(0x20) : 0; int dataSize = ((blocks - 1) * 0x2000 + lbTotal) * channels + 0x20; #if RSTMLIB //Create byte array byte[] array = new byte[rstmSize + headSize + adpcSize + dataSize]; fixed(byte *address = array) { #else //Create file map FileMap map = FileMap.FromTempFile(rstmSize + headSize + adpcSize + dataSize); VoidPtr address = map.Address; #endif //Get section pointers RSTMHeader * rstm = (RSTMHeader *)address; HEADHeader * head = (HEADHeader *)((byte *)rstm + rstmSize); ADPCHeader * adpc = (ADPCHeader *)((byte *)head + headSize); RSTMDATAHeader *data = (RSTMDATAHeader *)((byte *)adpc + adpcSize); //Initialize sections rstm->Set(headSize, adpcSize, dataSize); head->Set(headSize, channels, encoding); if (adpcSize > 0) { adpc->Set(adpcSize); } data->Set(dataSize); //Set HEAD data StrmDataInfo *part1 = head->Part1; part1->_format = new AudioFormatInfo((byte)encoding, (byte)(looped ? 1 : 0), (byte)channels, 0); part1->_sampleRate = (ushort)sampleRate; part1->_blockHeaderOffset = 0; part1->_loopStartSample = loopStart; part1->_numSamples = totalSamples; part1->_dataOffset = rstmSize + headSize + adpcSize + 0x20; part1->_numBlocks = blocks; part1->_blockSize = 0x2000; part1->_samplesPerBlock = samplesPerBlock; part1->_lastBlockSize = lbSize; part1->_lastBlockSamples = lbSamples; part1->_lastBlockTotal = lbTotal; part1->_dataInterval = encoding == WaveEncoding.ADPCM ? samplesPerBlock : 0; part1->_bitsPerSample = encoding == WaveEncoding.ADPCM ? 4 : 0; if (encoding == WaveEncoding.ADPCM) { //Create one ADPCMInfo for each channel int * adpcData = stackalloc int[channels]; ADPCMInfo **pAdpcm = (ADPCMInfo **)adpcData; for (int i = 0; i < channels; i++) { *(pAdpcm[i] = head->GetChannelInfo(i)) = new ADPCMInfo() { _pad = 0 } } ; //Create buffer for each channel int * bufferData = stackalloc int[channels]; short **channelBuffers = (short **)bufferData; int bufferSamples = totalSamples + 2; //Add two samples for initial yn values for (int i = 0; i < channels; i++) { channelBuffers[i] = tPtr = (short *)Marshal.AllocHGlobal(bufferSamples * 2); //Two bytes per sample //Zero padding samples and initial yn values for (int x = 0; x < (loopPadding + 2); x++) { *tPtr++ = 0; } } //Fill buffers stream.SamplePosition = 0; short *sampleBuffer = stackalloc short[channels]; for (int i = 2; i < bufferSamples; i++) { if (stream.SamplePosition == stream.LoopEndSample && looped) { stream.SamplePosition = stream.LoopStartSample; } stream.ReadSamples(sampleBuffer, 1); for (int x = 0; x < channels; x++) { channelBuffers[x][i] = sampleBuffer[x]; } } //Calculate coefs for (int i = 0; i < channels; i++) { AudioConverter.CalcCoefs(channelBuffers[i] + 2, totalSamples, (short *)pAdpcm[i], progress); } //Encode blocks byte * dPtr = (byte *)data->Data; bshort *pyn = (bshort *)adpc->Data; for (int x = 0; x < channels; x++) { *pyn++ = 0; *pyn++ = 0; } for (int sIndex = 0, bIndex = 1; sIndex < totalSamples; sIndex += samplesPerBlock, bIndex++) { int blockSamples = Math.Min(totalSamples - sIndex, samplesPerBlock); for (int x = 0; x < channels; x++) { short *sPtr = channelBuffers[x] + sIndex; //Set block yn values if (bIndex != blocks) { *pyn++ = sPtr[samplesPerBlock + 1]; *pyn++ = sPtr[samplesPerBlock]; } //Encode block (include yn in sPtr) AudioConverter.EncodeBlock(sPtr, blockSamples, dPtr, (short *)pAdpcm[x]); //Set initial ps if (bIndex == 1) { pAdpcm[x]->_ps = *dPtr; } //Advance output pointer if (bIndex == blocks) { //Fill remaining dPtr += lbSize; for (int i = lbSize; i < lbTotal; i++) { *dPtr++ = 0; } } else { dPtr += 0x2000; } } if (progress != null) { if ((sIndex % samplesPerBlock) == 0) { progress.Update(progress.CurrentValue + (0x7000 * channels)); } } } //Reverse coefs for (int i = 0; i < channels; i++) { short *p = pAdpcm[i]->_coefs; for (int x = 0; x < 16; x++, p++) { *p = p->Reverse(); } } //Write loop states if (looped) { //Can't we just use block states? int loopBlock = loopStart / samplesPerBlock; int loopChunk = (loopStart - (loopBlock * samplesPerBlock)) / 14; dPtr = (byte *)data->Data + (loopBlock * 0x2000 * channels) + (loopChunk * 8); tmp = (loopBlock == blocks - 1) ? lbTotal : 0x2000; for (int i = 0; i < channels; i++, dPtr += tmp) { //Use adjusted samples for yn values tPtr = channelBuffers[i] + loopStart; pAdpcm[i]->_lps = *dPtr; pAdpcm[i]->_lyn2 = *tPtr++; pAdpcm[i]->_lyn1 = *tPtr; } } //Free memory for (int i = 0; i < channels; i++) { Marshal.FreeHGlobal((IntPtr)channelBuffers[i]); } } else if (encoding == WaveEncoding.PCM16) { bshort *destPtr = (bshort *)data->Data; for (int i = 0; i < blocks; i++) { int samplesPerChannel = i < blocks - 1 ? part1->_samplesPerBlock : part1->_lastBlockSamples; int bytesPerChannel = i < blocks - 1 ? part1->_blockSize : part1->_lastBlockTotal; short[] sampleData = new short[channels * bytesPerChannel / sizeof(short)]; fixed(short *sampleDataPtr = sampleData) { int read = 0; do { if (stream.SamplePosition == stream.LoopEndSample && looped) { stream.SamplePosition = stream.LoopStartSample; } int s = stream.ReadSamples(sampleDataPtr + read, samplesPerChannel - read); if (s == 0) { throw new Exception("No samples could be read from the stream"); } read += s; }while (read < samplesPerChannel); } for (int j = 0; j < channels; j++) { for (int k = j; k < sampleData.Length; k += channels) { *(destPtr++) = sampleData[k]; } } progress.Update(progress.CurrentValue + (samplesPerChannel * channels * 3)); } } if (progress != null) { progress.Finish(); } #if RSTMLIB } return(array); #else return(map); #endif }
public virtual FileMap EncodeREFTTexture(Bitmap src, int mipLevels, WiiPaletteFormat format) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; ColorPalette pal = src.Palette; PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels) + 0x20 + (pal != null ? (pal.Entries.Length * 2) : 0)); try { //Build REFT image header REFTImageHeader *header = (REFTImageHeader *)fileView.Address; *header = new REFTImageHeader((ushort)w, (ushort)h, (byte)RawFormat, (byte)format, (ushort)(pal != null ? pal.Entries.Length : 0), (uint)fileView.Length - 0x20 - (uint)(pal != null ? (pal.Entries.Length * 2) : 0), (byte)(mipLevels - 1)); int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) for (int i = 1; i <= mipLevels; i++) { EncodeLevel((VoidPtr)header + 0x20, dib, src, dStep, sStep, i); } if (pal != null) { int count = pal.Entries.Length; switch (format) { case WiiPaletteFormat.IA8: { IA8Pixel *dPtr = (IA8Pixel *)header->PaletteData; for (int i = 0; i < count; i++) { dPtr[i] = (IA8Pixel)pal.Entries[i]; } break; } case WiiPaletteFormat.RGB565: { wRGB565Pixel *dPtr = (wRGB565Pixel *)header->PaletteData; for (int i = 0; i < count; i++) { dPtr[i] = (wRGB565Pixel)pal.Entries[i]; } break; } case WiiPaletteFormat.RGB5A3: { wRGB5A3Pixel *dPtr = (wRGB5A3Pixel *)header->PaletteData; for (int i = 0; i < count; i++) { dPtr[i] = (wRGB5A3Pixel)pal.Entries[i]; } break; } } } return(fileView); } catch (Exception x) { MessageBox.Show(x.ToString()); fileView.Dispose(); return(null); } }