Finalized model utilities

This commit is contained in:
AdAstra-LD 2021-04-09 06:11:43 +02:00
parent 43c4579fe5
commit d698e32d08
6 changed files with 315 additions and 223 deletions

View File

@ -51,29 +51,14 @@ namespace DSPRE {
string writingPath = Path.GetTempPath() + "BLDtexture.nsbtx";
byte[] txFile = File.ReadAllBytes(readingPath);
using (BinaryReader reader = new BinaryReader(new MemoryStream(txFile))) {
reader.BaseStream.Position = 0x8;
int nsbmdSize = reader.ReadInt32(); // Read size of NSBMD file
reader.BaseStream.Position = 0x14;
int texturesOffset = reader.ReadInt32(); // Read starting offset of embedded textures sections
int texturesSize = nsbmdSize - texturesOffset + 0x14; // Calculate size of embedded textures section
reader.BaseStream.Position = texturesOffset;
int lastReadPos;
using (BinaryWriter writer = new BinaryWriter(new FileStream(writingPath, FileMode.Create))) {
writer.Write(DSUtils.BuildNSBTXHeader(texturesSize));
lastReadPos = (int)reader.BaseStream.Position;
writer.Write(txFile, lastReadPos, txFile.Length - lastReadPos);
}
}
DSUtils.WriteToFile(writingPath, DSUtils.GetTexturesFromTexturedNSBMD(txFile), fromScratch: true);
}
private void FillListBox(bool interior) {
int modelCount = Directory.GetFiles(folder + rom.GetBuildingModelsDirPath(interior)).Length;
for (int currentIndex = 0; currentIndex < modelCount; currentIndex++) {
using (BinaryReader reader = new BinaryReader(File.OpenRead(folder + rom.GetBuildingModelsDirPath(interior) + "\\" + currentIndex.ToString("D4")))) {
string filePath = folder + rom.GetBuildingModelsDirPath(interior) + "\\" + currentIndex.ToString("D4");
using (BinaryReader reader = new BinaryReader(File.OpenRead(filePath))) {
string nsbmdName = ReadNSBMDname(reader);
buildingEditorBldListBox.Items.Add("[" + currentIndex.ToString("D3") + "] " + nsbmdName);
}

View File

@ -1,39 +1,68 @@
using NarcAPI;
using LibNDSFormats.NSBMD;
using NarcAPI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using static DSPRE.RomInfo;
namespace DSPRE {
static class DSUtils {
public static void WriteToFile(string filepath, byte[] bytesToWrite, uint writeAt = 0, int readFrom = 0) {
public static class DSUtils {
public const int NSBMD_DOESNTHAVE_TEXTURE = 0;
public const int NSBMD_HAS_TEXTURE = 1;
public static void WriteToFile(string filepath, byte[] bytesToWrite, uint writeAt = 0, int readFrom = 0, bool fromScratch = false) {
if (fromScratch)
File.Delete(filepath);
using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(filepath))) {
writer.BaseStream.Position = writeAt;
writer.Write(bytesToWrite, readFrom, bytesToWrite.Length - readFrom);
}
}
public static byte[] ReadFromFile(string filepath, long startOffset = 0, long numberOfBytes = 0) {
FileStream f = File.OpenRead(filepath);
BinaryReader reader = new BinaryReader(f);
reader.BaseStream.Position = startOffset;
byte[] buffer = null;
try {
if (numberOfBytes == 0) {
buffer = reader.ReadBytes((int)(f.Length - reader.BaseStream.Position));
} else {
buffer = reader.ReadBytes((int)numberOfBytes);
FileStream f = File.OpenRead(filepath);
using (BinaryReader reader = new BinaryReader(f)) {
reader.BaseStream.Position = startOffset;
try {
if (numberOfBytes == 0) {
buffer = reader.ReadBytes((int)(f.Length - reader.BaseStream.Position));
} else {
buffer = reader.ReadBytes((int)numberOfBytes);
}
} catch (EndOfStreamException) {
Console.WriteLine("Stream ended");
}
} catch (EndOfStreamException) {
Console.WriteLine("Stream ended");
} finally {
reader.Dispose();
}
return buffer;
}
public static byte[] ReadFromByteArray(byte[] input, long readFrom = 0, long numberOfBytes = 0) {
byte[] buffer = null;
using (BinaryReader reader = new BinaryReader(new MemoryStream(input))) {
reader.BaseStream.Position = readFrom;
try {
if (numberOfBytes == 0) {
buffer = reader.ReadBytes((int)(input.Length - reader.BaseStream.Position));
} else {
buffer = reader.ReadBytes((int)numberOfBytes);
}
} catch (EndOfStreamException) {
Console.WriteLine("Stream ended");
}
}
return buffer;
}
public static int DecompressOverlay(int overlayNumber, bool makeBackup) {
String overlayFilePath = GetOverlayPath(overlayNumber);
@ -204,10 +233,11 @@ namespace DSPRE {
opened.ExtractToFolder(paths.unpackedPath);
if (progress != null)
if (progress != null) {
try {
progress.Value++;
} catch (ArgumentOutOfRangeException) { }
}
}
}
}
@ -228,32 +258,104 @@ namespace DSPRE {
mdl0Data = modelReader.ReadBytes((int)mdl0Size);
}
using (BinaryWriter writer = new BinaryWriter(new MemoryStream())) {
MemoryStream output = new MemoryStream();
using (BinaryWriter writer = new BinaryWriter(output)) {
writer.Write(nsbmdHeaderData); // Write first header bytes, same for all NSBMD.
writer.Write(mdl0Size + 0x14);
writer.Write((short)0x10); // Writes BMD0 header size (always 16)
writer.Write((short)0x1); // Write new number of sub-files, since embedded textures are removed
writer.Write(0x14); // Writes new start offset of MDL0
writer.Write((uint)0x14); // Writes new start offset of MDL0
writer.Write(mdl0Data); // Writes MDL0;
return ((MemoryStream)writer.BaseStream).ToArray();
}
return output.ToArray();
}
public static byte[] BuildNSBTXHeader(int texturesSize) {
public static byte[] BuildNSBTXHeader(uint texturesSize) {
MemoryStream ms = new MemoryStream();
using (BinaryWriter bw = new BinaryWriter(ms)) {
bw.Write((UInt32)0x30585442); // Write magic code BTX0
bw.Write((UInt16)0xFEFF); // Byte order
bw.Write((UInt16)0x0001); // ???
bw.Write((UInt32)texturesSize); // Write size of textures block
bw.Write((UInt16)0x0010); //Header size???
bw.Write((UInt16)0x0001); //Number of blocks???
bw.Write((UInt32)0x00000014); // Offset to block
bw.Write(Encoding.UTF8.GetBytes("BTX0")); // Write magic code BTX0
bw.Write((ushort)0xFEFF); // Byte order
bw.Write((ushort)0x0001); // ???
bw.Write(texturesSize); // Write size of textures block
bw.Write((short)0x10); //Header size
bw.Write((short)0x01); //Number of sub-files???
bw.Write((uint)0x14); // Offset to sub-file
}
return ms.ToArray();
}
public static byte[] GetTexturesFromTexturedNSBMD(byte[] modelFile) {
using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) {
byteArrReader.BaseStream.Position = 20;
int texAbsoluteOffset = byteArrReader.ReadInt32();
byteArrReader.BaseStream.Position = texAbsoluteOffset + 4;
uint textureSize = byteArrReader.ReadUInt32();
byte[] nsbtxHeader = DSUtils.BuildNSBTXHeader(20 + textureSize);
byte[] texData = DSUtils.ReadFromByteArray(modelFile, readFrom: texAbsoluteOffset);
byte[] output = new byte[nsbtxHeader.Length + texData.Length];
Buffer.BlockCopy(nsbtxHeader, 0, output, 0, nsbtxHeader.Length);
Buffer.BlockCopy(texData, 0, output, nsbtxHeader.Length, texData.Length);
return output;
}
}
public static int CheckNSBMDHeader(byte[] modelFile) {
using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) {
if (byteArrReader.ReadUInt32() != NSBMD.NDS_TYPE_BMD0) {
MessageBox.Show("Please select an NSBMD file.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error);
return -1;
}
byteArrReader.BaseStream.Position = 0xE;
return byteArrReader.ReadInt16() >= 2 ? NSBMD_HAS_TEXTURE : NSBMD_DOESNTHAVE_TEXTURE;
}
}
public static byte[] BuildNSBMDwithTextures(byte[] nsbmd, byte[] nsbtx) {
byte[] wholeTEX0 = GetFirstBlock(nsbtx);
byte[] wholeMDL0 = GetFirstBlock(nsbmd);
MemoryStream ms = new MemoryStream();
using (BinaryReader nsbmdReader = new BinaryReader(new MemoryStream(nsbmd))) {
using (BinaryWriter msWriter = new BinaryWriter(ms)) {
msWriter.Write(nsbmdReader.ReadInt32()); //BMD0 segment
msWriter.Write(nsbmdReader.ReadInt32()); //Byte order??? segment
msWriter.Write(wholeMDL0.Length + wholeTEX0.Length + NSBMD.HEADERSIZE);
nsbmdReader.BaseStream.Position += 4;
msWriter.Write(nsbmdReader.ReadUInt16()); //Header size, always 16
msWriter.Write((ushort)0x2); //Number of blocks, now it's 2 because we are inserting textures
nsbmdReader.BaseStream.Position += 2;
msWriter.Write((uint)msWriter.BaseStream.Position + (4 * 2)); //Absolute offset to model data. We are gonna have to write two offsets
nsbmdReader.BaseStream.Position += 4;
msWriter.Write((uint)nsbmdReader.ReadUInt32()); //Copy offset to TEX0
msWriter.Write(wholeMDL0);
msWriter.Write(wholeTEX0);
}
}
return ms.ToArray();
}
private static byte[] GetFirstBlock(byte[] NSBFile) {
int blockSize;
uint offsetToMainBlock;
using (BinaryReader reader = new BinaryReader(new MemoryStream(NSBFile))) {
reader.BaseStream.Position = 16;
offsetToMainBlock = reader.ReadUInt32();
reader.BaseStream.Position = offsetToMainBlock + 4;
blockSize = reader.ReadInt32();
}
byte[] blockData = new byte[blockSize];
Buffer.BlockCopy(NSBFile, (int)offsetToMainBlock, blockData, 0, blockSize);
return blockData;
}
}
}

View File

@ -5,13 +5,11 @@ using System.Text;
using System.IO;
using LibNDSFormats.NSBMD;
namespace LibNDSFormats.NSBCA
{
namespace LibNDSFormats.NSBCA {
/// <summary>
/// Loader for NSBCA files & data.
/// </summary>
public static class NSBCALoader
{
public static class NSBCALoader {
#region Methods (2)
// Public Methods (2)
@ -21,27 +19,24 @@ namespace LibNDSFormats.NSBCA
/// </summary>
/// <param name="stream">Stream to use.</param>
/// <returns>Material definitions.</returns>
public static IEnumerable<NSBMDAnimation> LoadNsbca(Stream stream)
{
public static IEnumerable<NSBMDAnimation> LoadNsbca(Stream stream) {
List<NSBMDAnimation> animation = new List<NSBMDAnimation>();
var reader = new EndianBinaryReader(stream, Endianness.LittleEndian);
byte[] id = reader.ReadBytes(4);
if (id == new byte[] { 0x42, 0x43, 0x41, 0x30 })
{
throw new Exception();
if (id == new byte[] { 0x42, 0x43, 0x41, 0x30 }) {
throw new Exception();
}
int i = reader.ReadInt32();
if (i == NSBMD.NSBMD.NDS_TYPE_MAGIC1)
{
reader.BaseStream.Position += 2;
int i = reader.ReadUInt16();
if (i == NSBMD.NSBMD.NDS_TYPE_UNK1) {
i = reader.ReadInt32();
if (i == stream.Length)
{
if (i == stream.Length) {
int numblock = reader.ReadInt32();
numblock >>= 16;
int r = reader.ReadInt32();
id = reader.ReadBytes(4);
if (numblock == 1 && r == 0x14)
{
if (numblock == 1 && r == 0x14) {
animation.AddRange(ReadJnt0(stream, 0x14));
}
}
@ -55,11 +50,9 @@ namespace LibNDSFormats.NSBCA
/// </summary>
/// <param name="stream">File to use.</param>
/// <returns>Material definitions.</returns>
public static IEnumerable<NSBMDAnimation> LoadNsbca(FileInfo fileInfo)
{
public static IEnumerable<NSBMDAnimation> LoadNsbca(FileInfo fileInfo) {
IEnumerable<NSBMDAnimation> result = null;
using (var fileStream = new FileStream(fileInfo.FullName, FileMode.Open))
{
using (var fileStream = new FileStream(fileInfo.FullName, FileMode.Open)) {
result = LoadNsbca(fileStream);
}
return result;
@ -70,8 +63,7 @@ namespace LibNDSFormats.NSBCA
/// </summary>
/// <param name="stream">Stream to use.</param>
/// <returns>Material definitions.</returns>
public static IEnumerable<NSBMDAnimation> ReadJnt0(Stream stream, int blockoffset)
{
public static IEnumerable<NSBMDAnimation> ReadJnt0(Stream stream, int blockoffset) {
EndianBinaryReader reader = new EndianBinaryReader(stream, Endianness.LittleEndian);
int blocksize, blockptr, blocklimit;
int num, objnum, i, j, r;
@ -104,11 +96,10 @@ namespace LibNDSFormats.NSBCA
//fseek( fnsbca, 16 * num, SEEK_CUR ); // skip names
blockptr += 16 * num;
for (i = 0; i < num; i++)
{
for (i = 0; i < num; i++) {
reader.BaseStream.Seek(dataoffset[i], SeekOrigin.Begin);
//j = getdword();
if (reader.ReadBytes(4) == new byte[] {0x4A,0x00,0x41,0x43 }) return null;
if (reader.ReadBytes(4) == new byte[] { 0x4A, 0x00, 0x41, 0x43 }) return null;
blockptr += 4;
animlen.Add(getword(reader.ReadBytes(2)));
@ -127,90 +118,58 @@ namespace LibNDSFormats.NSBCA
sec2offset = getdword(reader.ReadBytes(4)) + dataoffset[i];
blockptr += 8;
for (j = 0; j < objnum; j++)
{
for (j = 0; j < objnum; j++) {
animation[j] = new NSBMDAnimation();
animation[j].dataoffset = getword(reader.ReadBytes(2)) + dataoffset[i];
}
for (j = 0; j < objnum; j++)
{
for (j = 0; j < objnum; j++) {
NSBMD.NSBMDAnimation anim = animation[j];
r = getdword(reader.ReadBytes(4));
anim.flag = r;
// if ((r >> 1 & 1) == 0)
// if ((r >> 1 & 1) == 0)
//{ // any transformation?
if ((r >> 1 & 1) == 0)
{ // translation
if ((r & 4) == 1)
{ // use Base T
if ((r >> 1 & 1) == 0) { // translation
if ((r & 4) == 1) { // use Base T
} else {
if ((r & 8) == 1) { // consTX
anim.m_trans[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
} else {
}
else
{
if ((r & 8) == 1)
{ // consTX
anim.m_trans[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
}
else
{
}
if ((r & 0x10) == 1)
{ // consTY
anim.m_trans[1] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
}
else
{
}
if ((r & 0x20) == 1)
{ // consTZ
anim.m_trans[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
}
else
{
}
if ((r & 0x10) == 1) { // consTY
anim.m_trans[1] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
} else {
}
if ((r & 0x20) == 1) { // consTZ
anim.m_trans[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
} else {
}
}
if ((r >> 6 & 1) == 0)
{ // rotation
if ((r & 0x100) == 1)
{ // constR
anim.a = ((float)getword(reader.ReadBytes(2))) / 4096.0f;
anim.b = ((float)getword(reader.ReadBytes(2))) / 4096.0f;
}
if ((r >> 6 & 1) == 0) { // rotation
if ((r & 0x100) == 1) { // constR
anim.a = ((float)getword(reader.ReadBytes(2))) / 4096.0f;
anim.b = ((float)getword(reader.ReadBytes(2))) / 4096.0f;
} else {
}
}
if ((r >> 9 & 1) == 0) { // scale
if ((r & 0x400) == 1) { // use Base S
} else {
if ((r & 0x800) == 1) { // consSX
anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
} else {
}
else
{
if ((r & 0x1000) == 1) {// consSY
anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
} else {
}
if ((r & 0x2000) == 1) {// consSZ
anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
} else {
}
}
if ((r >> 9 & 1) == 0)
{ // scale
if ((r & 0x400) == 1)
{ // use Base S
}
else
{
if ((r & 0x800) == 1)
{ // consSX
anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
}
else
{
}
if ((r & 0x1000) == 1)
{// consSY
anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
}
else
{
}
if ((r & 0x2000) == 1)
{// consSZ
anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
}
else
{
}
}
// }
// }
}
animation[j] = anim;
}
@ -220,8 +179,7 @@ namespace LibNDSFormats.NSBCA
//free(dataoffset);
return animation;
}
static Int32 getdword(byte[] b)
{
static Int32 getdword(byte[] b) {
Int32 v;
v = b[0];
v |= b[1] << 8;
@ -229,13 +187,12 @@ namespace LibNDSFormats.NSBCA
v |= b[3] << 24;
return v;
}
static Int32 getword(byte[] b)
{
static Int32 getword(byte[] b) {
Int32 v;
v = b[0];
v |= b[1] << 8;
return v;
}
}
#endregion Methods
}
}

View File

@ -20,12 +20,14 @@ namespace LibNDSFormats.NSBMD
#region Constants
public const int NDS_TYPE_MDL0 = 0x304c444d;
public const int NDS_TYPE_TEX0 = 0x30584554;
public const int NDS_TYPE_BMD0 = 0x30444d42;
public const int NDS_TYPE_MAGIC2 = 0x0002feff;
public const int NDS_TYPE_MAGIC1 = 0x0001feff;
public const int NDS_TYPE_BTX0 = 0x30585442;
public const uint NDS_TYPE_MDL0 = 0x304c444d;
public const uint NDS_TYPE_TEX0 = 0x30584554;
public const uint NDS_TYPE_BMD0 = 0x30444d42;
public const ushort NDS_TYPE_BYTEORDER = 0xfeff;
public const ushort NDS_TYPE_UNK2 = 0x0002;
public const ushort NDS_TYPE_UNK1 = 0x0001;
public const uint NDS_TYPE_BTX0 = 0x30585442;
public const uint HEADERSIZE = 16;
#endregion Constants
@ -1166,12 +1168,19 @@ namespace LibNDSFormats.NSBMD
tmp = reader.ReadInt32();
if (tmp != NDS_TYPE_BMD0)
throw new Exception();
tmp = reader.ReadInt32();
if (tmp != NDS_TYPE_MAGIC2)
tmp = reader.ReadUInt16();
if (tmp != NDS_TYPE_BYTEORDER)
throw new Exception();
tmp = reader.ReadUInt16();
if (tmp != NDS_TYPE_UNK2)
throw new Exception();
int filesize = reader.ReadInt32();
if (filesize > stream.Length)
throw new Exception();
int numblock = reader.ReadInt32();
numblock >>= 16;
if (numblock == 0)
@ -1192,11 +1201,10 @@ namespace LibNDSFormats.NSBMD
for (int i = 0; i < numblock; i++)
{
stream.Position = blockoffset[i];
int id = reader.ReadInt32();
uint id = reader.ReadUInt32();
int texnum = 0, palnum = 0;
switch (id)
{
switch (id) {
case NDS_TYPE_MDL0:
result.models = ReadMdl0(stream, blockoffset[i]);

View File

@ -37,8 +37,9 @@ namespace LibNDSFormats.NSBTX
return null;
}
int i = reader.ReadInt32();
if (i == NSBMD.NSBMD.NDS_TYPE_MAGIC1) {
reader.BaseStream.Position += 2;
int i = reader.ReadUInt16();
if (i == NSBMD.NSBMD.NDS_TYPE_UNK1) {
i = reader.ReadInt32();
if (i == stream.Length) {

View File

@ -709,6 +709,108 @@ namespace DSPRE {
private void scriptCommandsDatabaseToolStripButton_Click(object sender, EventArgs e) {
OpenCommandsDatabase(RomInfo.ScriptCommandNamesDict, RomInfo.CommandParametersDict);
}
private void nsbmdExportTexButton_Click(object sender, EventArgs e) {
OpenFileDialog of = new OpenFileDialog {
Filter = "Textured NSBMD File(*.nsbmd)|*.nsbmd"
};
if (of.ShowDialog(this) != DialogResult.OK)
return;
byte[] modelFile = DSUtils.ReadFromFile(of.FileName);
if (DSUtils.CheckNSBMDHeader(modelFile) == DSUtils.NSBMD_DOESNTHAVE_TEXTURE) {
MessageBox.Show("This NSBMD file is already untextured.", "No textures to remove", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
MessageBox.Show("Choose where to save the textures.", "Choose destination path", MessageBoxButtons.OK, MessageBoxIcon.Information);
SaveFileDialog texSf = new SaveFileDialog {
Filter = "NSBTX File(*.nsbtx)|*.nsbtx",
FileName = Path.GetFileNameWithoutExtension(of.FileName)
};
if (texSf.ShowDialog() != DialogResult.OK)
return;
DSUtils.WriteToFile(texSf.FileName, DSUtils.GetTexturesFromTexturedNSBMD(modelFile));
}
private void nsbmdRemoveTexButton_Click(object sender, EventArgs e) {
OpenFileDialog of = new OpenFileDialog {
Filter = "Textured NSBMD File(*.nsbmd)|*.nsbmd"
};
if (of.ShowDialog(this) != DialogResult.OK)
return;
byte[] modelFile = DSUtils.ReadFromFile(of.FileName);
if (DSUtils.CheckNSBMDHeader(modelFile) == DSUtils.NSBMD_DOESNTHAVE_TEXTURE) {
MessageBox.Show("This NSBMD file is already untextured.", "No textures to remove", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
string extramsg = "";
DialogResult d = MessageBox.Show("Would you like to save the removed textures to a file?", "Save textures?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (d.Equals(DialogResult.Yes)) {
MessageBox.Show("Choose where to save the textures.", "Choose destination path", MessageBoxButtons.OK, MessageBoxIcon.Information);
SaveFileDialog texSf = new SaveFileDialog {
Filter = "NSBTX File(*.nsbtx)|*.nsbtx",
FileName = Path.GetFileNameWithoutExtension(of.FileName)
};
if (texSf.ShowDialog() == DialogResult.OK) {
DSUtils.WriteToFile(texSf.FileName, DSUtils.GetTexturesFromTexturedNSBMD(modelFile));
extramsg = " exported and";
}
}
MessageBox.Show("Choose where to save the untextured model.", "Choose destination path", MessageBoxButtons.OK, MessageBoxIcon.Information);
SaveFileDialog sf = new SaveFileDialog {
Filter = "Untextured NSBMD File(*.nsbmd)|*.nsbmd",
FileName = Path.GetFileNameWithoutExtension(of.FileName) + "_untextured"
};
if (sf.ShowDialog(this) != DialogResult.OK)
return;
DSUtils.WriteToFile(sf.FileName, DSUtils.GetModelWithoutTextures(modelFile));
MessageBox.Show("Textures correctly" + extramsg + " removed!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void nsbmdAddTexButton_Click(object sender, EventArgs e) {
OpenFileDialog of = new OpenFileDialog {
Filter = "NSBMD File(*.nsbmd)|*.nsbmd"
};
if (of.ShowDialog(this) != DialogResult.OK)
return;
byte[] modelFile = File.ReadAllBytes(of.FileName);
if (DSUtils.CheckNSBMDHeader(modelFile) == DSUtils.NSBMD_HAS_TEXTURE) {
DialogResult d = MessageBox.Show("This NSBMD file is already textured.\nDo you want to overwrite its textures?", "Textures found", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (d.Equals(DialogResult.No)) {
return;
}
}
MessageBox.Show("Select the new NSBTX texture file.", "Choose NSBTX", MessageBoxButtons.OK, MessageBoxIcon.Information);
OpenFileDialog openNsbtx = new OpenFileDialog {
Filter = "NSBTX File(*.nsbtx)|*.nsbtx"
};
if (openNsbtx.ShowDialog(this) != DialogResult.OK)
return;
byte[] textureFile = File.ReadAllBytes(openNsbtx.FileName);
MessageBox.Show("Choose where to save the new textured model.", "Choose destination path", MessageBoxButtons.OK, MessageBoxIcon.Information);
string texturedPath = Path.GetFileNameWithoutExtension(of.FileName);
SaveFileDialog sf = new SaveFileDialog {
Filter = "Textured NSBMD File(*.nsbmd)|*.nsbmd",
FileName = texturedPath.Substring(0, texturedPath.Length - "_untextured".Length) + "_textured"
};
if (sf.ShowDialog(this) != DialogResult.OK)
return;
DSUtils.WriteToFile(sf.FileName, DSUtils.BuildNSBMDwithTextures(modelFile, textureFile), fromScratch: true);
MessageBox.Show("Textures correctly written to NSBMD file.", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void OpenCommandsDatabase(Dictionary<ushort, string> namesDict, Dictionary<ushort, byte[]> paramsDict) {
statusLabel.Text = "Setting up Commands Database. Please wait...";
Update();
@ -6318,68 +6420,5 @@ namespace DSPRE {
MessageBox.Show("AreaData File imported successfully!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion
private void nsbmdExportTexButton_Click(object sender, EventArgs e) {
}
private void nsbmdRemoveTexButton_Click(object sender, EventArgs e) {
OpenFileDialog of = new OpenFileDialog();
of.Filter = "Textured NSBMD File(*.nsbmd)|*.nsbmd";
if (of.ShowDialog(this) != DialogResult.OK)
return;
byte[] modelFile = DSUtils.ReadFromFile(of.FileName);
string extramsg = "";
using (BinaryReader reader = new BinaryReader(new MemoryStream(modelFile))) {
if (reader.ReadUInt32() != NSBMD.NDS_TYPE_BMD0) {
MessageBox.Show("Please select an NSBMD file.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
reader.BaseStream.Position = 0xE;
if (reader.ReadInt16() < 2) {
MessageBox.Show("This NSBMD file doesn't contain any textures.", "No textures found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
DialogResult d = MessageBox.Show("Would you like to save the removed textures to a file?", "Save textures?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (d.Equals(DialogResult.Yes)) {
MessageBox.Show("Choose where to save the textures.", "Choose destination path", MessageBoxButtons.OK, MessageBoxIcon.Information);
SaveFileDialog texSf = new SaveFileDialog();
texSf.Filter = "NSBTX File(*.nsbtx)|*.nsbtx";
texSf.FileName = Path.GetFileNameWithoutExtension(of.FileName);
if (texSf.ShowDialog(this) != DialogResult.OK)
return;
int bmdAbsoluteOffset = reader.ReadInt32();
int texAbsoluteOffset = reader.ReadInt32();
reader.BaseStream.Position = texAbsoluteOffset + 4;
int textureSize = reader.ReadInt32();
DSUtils.WriteToFile(texSf.FileName, DSUtils.BuildNSBTXHeader(20 + textureSize));
DSUtils.WriteToFile(texSf.FileName, DSUtils.ReadFromFile(of.FileName, texAbsoluteOffset), 20);
extramsg = "and exported";
}
}
MessageBox.Show("Choose where to save the untextured model.", "Choose destination path", MessageBoxButtons.OK, MessageBoxIcon.Information);
SaveFileDialog sf = new SaveFileDialog();
sf.Filter = "Untextured NSBMD File(*.nsbmd)|*.nsbmd";
sf.FileName = Path.GetFileNameWithoutExtension(of.FileName) + "_untextured";
if (sf.ShowDialog(this) != DialogResult.OK)
return;
DSUtils.WriteToFile(sf.FileName, DSUtils.GetModelWithoutTextures(modelFile));
MessageBox.Show("Textures correctly removed " + extramsg + '!', "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void nsbmdAddTexButton_Click(object sender, EventArgs e) {
}
}
}