mirror of
https://github.com/AdAstra-LD/DS-Pokemon-Rom-Editor.git
synced 2026-05-09 21:50:57 -05:00
Finalized model utilities
This commit is contained in:
parent
43c4579fe5
commit
d698e32d08
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user