mirror of
https://github.com/AdAstra-LD/DS-Pokemon-Rom-Editor.git
synced 2026-05-09 12:51:54 -05:00
303 lines
12 KiB
C#
303 lines
12 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using LibNDSFormats.NSBMD;
|
|
using LibNDSFormats.NSBTX;
|
|
using Microsoft.WindowsAPICodePack.Dialogs;
|
|
using Tao.OpenGl;
|
|
using static DSPRE.RomInfo;
|
|
|
|
namespace DSPRE {
|
|
public partial class BuildingEditor : Form {
|
|
#region Variables
|
|
public static string temp_btxname = "BLDtexture.nsbtx";
|
|
private readonly string folder;
|
|
bool disableHandlers = new bool();
|
|
readonly RomInfo rom;
|
|
|
|
NSBMD currentNSBMD;
|
|
byte[] currentModelData;
|
|
|
|
readonly NSBMDGlRenderer renderer = new NSBMDGlRenderer();
|
|
|
|
public static float ang = 0.0f;
|
|
public static float dist = 12.8f;
|
|
public static float elev = 50.0f;
|
|
public static float tempAng = 0.0f;
|
|
public static float tempDist = 0.0f;
|
|
public static float tempElev = 0.0f;
|
|
public float perspective = 45f;
|
|
|
|
/* Bld Rotation vars */
|
|
public bool lRot;
|
|
public bool rRot;
|
|
public bool uRot;
|
|
public bool dRot;
|
|
#endregion
|
|
|
|
public BuildingEditor(RomInfo romInfo) {
|
|
InitializeComponent();
|
|
rom = romInfo;
|
|
|
|
buildingOpenGLControl.InitializeContexts();
|
|
buildingOpenGLControl.MakeCurrent();
|
|
buildingOpenGLControl.MouseWheel += new MouseEventHandler(buildingOpenGLControl_MouseWheel);
|
|
Gl.glEnable(Gl.GL_TEXTURE_2D);
|
|
|
|
if (RomInfo.gameFamily == gFamEnum.HGSS) {
|
|
interiorCheckBox.Enabled = true;
|
|
}
|
|
|
|
disableHandlers = true;
|
|
FillListBox(false);
|
|
FillTexturesBox();
|
|
textureComboBox.SelectedIndex = 0;
|
|
disableHandlers = false;
|
|
buildingEditorBldListBox.SelectedIndex = 0;
|
|
}
|
|
|
|
#region Subroutines
|
|
private void CreateEmbeddedTexturesFile(int modelID, bool interior) {
|
|
string readingPath = folder + rom.GetBuildingModelsDirPath(interior) + "\\" + modelID.ToString("D4");
|
|
|
|
byte[] txFile = File.ReadAllBytes(readingPath);
|
|
byte[] texData = NSBUtils.GetTexturesFromTexturedNSBMD(txFile);
|
|
|
|
if (texData.Length <= 4) {
|
|
Console.WriteLine("No textures found");
|
|
return;
|
|
}
|
|
DSUtils.WriteToFile(Path.GetTempPath() + temp_btxname, texData, fmode: FileMode.Create);
|
|
}
|
|
private void FillListBox(bool interior) {
|
|
int modelCount = Directory.GetFiles(folder + rom.GetBuildingModelsDirPath(interior)).Length;
|
|
for (int currentIndex = 0; currentIndex < modelCount; currentIndex++) {
|
|
string filePath = folder + rom.GetBuildingModelsDirPath(interior) + "\\" + currentIndex.ToString("D4");
|
|
|
|
using (DSUtils.EasyReader reader = new DSUtils.EasyReader(filePath, 0x14)) {
|
|
string nsbmdName = NSBUtils.ReadNSBMDname(reader);
|
|
buildingEditorBldListBox.Items.Add("[" + currentIndex.ToString("D3") + "] " + nsbmdName);
|
|
}
|
|
}
|
|
}
|
|
private void FillTexturesBox() {
|
|
int texturesCount = Directory.GetFiles(folder + RomInfo.gameDirs[DirNames.buildingTextures].unpackedDir).Length;
|
|
textureComboBox.Items.Add("Embedded textures");
|
|
|
|
for (int i = 0; i < texturesCount; i++) {
|
|
textureComboBox.Items.Add("Texture " + i);
|
|
}
|
|
}
|
|
private void LoadModelTextures(int fileID) {
|
|
string path;
|
|
if (fileID > -1) {
|
|
path = folder + RomInfo.gameDirs[RomInfo.DirNames.buildingTextures].unpackedDir + "\\" + fileID.ToString("D4");
|
|
} else {
|
|
path = Path.GetTempPath() + temp_btxname; // Load Embedded textures if the argument passed to this function is -1
|
|
}
|
|
|
|
try {
|
|
currentNSBMD.materials = NSBTXLoader.LoadNsbtx(new MemoryStream(File.ReadAllBytes(path)), out currentNSBMD.Textures, out currentNSBMD.Palettes);
|
|
currentNSBMD.MatchTextures();
|
|
} catch { }
|
|
}
|
|
private void RenderModel() {
|
|
MKDS_Course_Editor.NSBTA.NSBTA.NSBTA_File bta = new MKDS_Course_Editor.NSBTA.NSBTA.NSBTA_File();
|
|
MKDS_Course_Editor.NSBTP.NSBTP.NSBTP_File btp = new MKDS_Course_Editor.NSBTP.NSBTP.NSBTP_File();
|
|
MKDS_Course_Editor.NSBCA.NSBCA.NSBCA_File bca = new MKDS_Course_Editor.NSBCA.NSBCA.NSBCA_File();
|
|
int[] aniframeS = new int[0];
|
|
|
|
buildingOpenGLControl.Invalidate(); // Invalidate drawing surface
|
|
SetupRenderer(ang, dist, elev, perspective); // Adjust rendering settings
|
|
|
|
/* Render the building model */
|
|
renderer.Model = currentNSBMD.models[0];
|
|
Gl.glScalef(currentNSBMD.models[0].modelScale / 32, currentNSBMD.models[0].modelScale / 32, currentNSBMD.models[0].modelScale / 32);
|
|
renderer.RenderModel("", bta, aniframeS, aniframeS, aniframeS, aniframeS, aniframeS, bca, false, -1, 0.0f, 0.0f, dist, elev, ang, true, btp, currentNSBMD);
|
|
}
|
|
private void SetupRenderer(float ang, float dist, float elev, float perspective) {
|
|
Gl.glEnable(Gl.GL_RESCALE_NORMAL);
|
|
Gl.glEnable(Gl.GL_COLOR_MATERIAL);
|
|
Gl.glEnable(Gl.GL_DEPTH_TEST);
|
|
Gl.glEnable(Gl.GL_NORMALIZE);
|
|
Gl.glDisable(Gl.GL_CULL_FACE);
|
|
Gl.glFrontFace(Gl.GL_CCW);
|
|
Gl.glClearDepth(1);
|
|
Gl.glEnable(Gl.GL_ALPHA_TEST);
|
|
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
|
|
Gl.glEnable(Gl.GL_BLEND);
|
|
Gl.glAlphaFunc(Gl.GL_GREATER, 0f);
|
|
Gl.glClearColor(51f / 255f, 51f / 255f, 51f / 255f, 1f);
|
|
float aspect;
|
|
Gl.glViewport(0, 0, buildingOpenGLControl.Width, buildingOpenGLControl.Height);
|
|
aspect = buildingOpenGLControl.Width / buildingOpenGLControl.Height;//(vp[2] - vp[0]) / (vp[3] - vp[1]);
|
|
Gl.glMatrixMode(Gl.GL_PROJECTION);
|
|
Gl.glLoadIdentity();
|
|
Glu.gluPerspective(perspective, aspect, 0.2f, 500.0f);//0.02f, 32.0f);
|
|
Gl.glTranslatef(0, 0, -dist);
|
|
Gl.glRotatef(elev, 1, 0, 0);
|
|
Gl.glRotatef(ang, 0, 1, 0);
|
|
Gl.glMatrixMode(Gl.GL_MODELVIEW);
|
|
Gl.glLoadIdentity();
|
|
Gl.glTranslatef(0, 0, -dist);
|
|
Gl.glRotatef(elev, 1, 0, 0);
|
|
Gl.glRotatef(-ang, 0, 1, 0);
|
|
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, new float[] { 1, 1, 1, 0 });
|
|
Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, new float[] { 1, 1, 1, 0 });
|
|
Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_POSITION, new float[] { 1, 1, 1, 0 });
|
|
Gl.glLightfv(Gl.GL_LIGHT3, Gl.GL_POSITION, new float[] { 1, 1, 1, 0 });
|
|
Gl.glLoadIdentity();
|
|
Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);
|
|
Gl.glColor3f(1.0f, 1.0f, 1.0f);
|
|
Gl.glDepthMask(Gl.GL_TRUE);
|
|
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
#endregion
|
|
|
|
private void buildingOpenGLControl_MouseWheel(object sender, MouseEventArgs e) { // Zoom In/Out
|
|
float val = (float)e.Delta / 200;
|
|
|
|
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) {
|
|
dist += val;
|
|
} else {
|
|
dist -= val;
|
|
}
|
|
|
|
RenderModel();
|
|
}
|
|
private void buildingEditorListBox_SelectedIndexChanged(object sender, EventArgs e) {
|
|
if (disableHandlers || buildingEditorBldListBox.SelectedIndex < 0) {
|
|
return;
|
|
}
|
|
|
|
string path = folder + rom.GetBuildingModelsDirPath(interiorCheckBox.Checked) + "\\" + buildingEditorBldListBox.SelectedIndex.ToString("D4");
|
|
|
|
currentModelData = File.ReadAllBytes(path);
|
|
currentNSBMD = NSBMDLoader.LoadNSBMD(new MemoryStream(currentModelData));
|
|
|
|
CreateEmbeddedTexturesFile(buildingEditorBldListBox.SelectedIndex, interiorCheckBox.Checked);
|
|
LoadModelTextures(textureComboBox.SelectedIndex - 1);
|
|
RenderModel();
|
|
}
|
|
private void exportButton_Click(object sender, EventArgs e) {
|
|
SaveFileDialog em = new SaveFileDialog {
|
|
Filter = "NSBMD model (*.nsbmd)|*.nsbmd",
|
|
FileName = buildingEditorBldListBox.SelectedItem.ToString()
|
|
};
|
|
if (em.ShowDialog(this) != DialogResult.OK) {
|
|
return;
|
|
}
|
|
|
|
File.Copy(folder + rom.GetBuildingModelsDirPath(interiorCheckBox.Checked) + "\\" + buildingEditorBldListBox.SelectedIndex.ToString("D4"), em.FileName, true);
|
|
}
|
|
private void importButton_Click(object sender, EventArgs e) {
|
|
OpenFileDialog im = new OpenFileDialog {
|
|
Filter = "NSBMD model (*.nsbmd)|*.nsbmd"
|
|
};
|
|
if (im.ShowDialog(this) != DialogResult.OK) {
|
|
return;
|
|
}
|
|
|
|
using (DSUtils.EasyReader reader = new DSUtils.EasyReader(im.FileName)) {
|
|
if (reader.ReadUInt32() != NSBMD.NDS_TYPE_BMD0) {
|
|
MessageBox.Show("Please select an NSBMD file.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
return;
|
|
} else {
|
|
int currentIndex = buildingEditorBldListBox.SelectedIndex;
|
|
|
|
File.Copy(im.FileName, folder + rom.GetBuildingModelsDirPath(interiorCheckBox.Checked) + "\\" + currentIndex.ToString("D4"), true);
|
|
buildingEditorBldListBox.Items[currentIndex] = "[" + currentIndex.ToString("D3") + "] " + NSBUtils.ReadNSBMDname(reader, 0x14);
|
|
buildingEditorListBox_SelectedIndexChanged(null, null);
|
|
}
|
|
}
|
|
}
|
|
private void interiorCheckBox_CheckedChanged(object sender, EventArgs e) {
|
|
disableHandlers = true;
|
|
|
|
buildingEditorBldListBox.Items.Clear();
|
|
FillListBox(interiorCheckBox.Checked);
|
|
|
|
disableHandlers = false;
|
|
|
|
buildingEditorBldListBox.SelectedIndex = 0;
|
|
}
|
|
private void textureComboBox_SelectedIndexChanged(object sender, EventArgs e) {
|
|
if (disableHandlers) {
|
|
return;
|
|
}
|
|
LoadModelTextures(textureComboBox.SelectedIndex - 1);
|
|
RenderModel();
|
|
}
|
|
private void buildingOpenGLControl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
|
|
byte multiplier = 2;
|
|
if (e.Modifiers == Keys.Shift) {
|
|
multiplier = 1;
|
|
} else if (e.Modifiers == Keys.Control) {
|
|
multiplier = 4;
|
|
}
|
|
|
|
switch (e.KeyCode) {
|
|
case Keys.Right:
|
|
rRot = true;
|
|
lRot = false;
|
|
break;
|
|
case Keys.Left:
|
|
rRot = false;
|
|
lRot = true;
|
|
break;
|
|
case Keys.Up:
|
|
dRot = false;
|
|
uRot = true;
|
|
break;
|
|
case Keys.Down:
|
|
dRot = true;
|
|
uRot = false;
|
|
break;
|
|
}
|
|
|
|
if (rRot ^ lRot) {
|
|
if (rRot) {
|
|
ang += 1 * multiplier;
|
|
} else if (lRot) {
|
|
ang -= 1 * multiplier;
|
|
}
|
|
}
|
|
|
|
if (uRot ^ dRot) {
|
|
if (uRot) {
|
|
elev -= 1 * multiplier;
|
|
} else if (dRot) {
|
|
elev += 1 * multiplier;
|
|
}
|
|
}
|
|
RenderModel();
|
|
}
|
|
|
|
private void bldExportDAEbutton_Click(object sender, EventArgs e) {
|
|
DSUtils.ModelToDAE(
|
|
modelName: buildingEditorBldListBox.SelectedItem.ToString().TrimEnd('\0'),
|
|
modelData: currentModelData,
|
|
textureData: textureComboBox.SelectedIndex < 1 ? null : File.ReadAllBytes(RomInfo.gameDirs[DirNames.buildingTextures].unpackedDir + "\\" + (textureComboBox.SelectedIndex - 1).ToString("D4"))
|
|
);
|
|
}
|
|
|
|
private void buildingOpenGLControl_KeyUp(object sender, KeyEventArgs e) {
|
|
switch (e.KeyCode) {
|
|
case Keys.Right:
|
|
rRot = false;
|
|
break;
|
|
case Keys.Left:
|
|
lRot = false;
|
|
break;
|
|
case Keys.Up:
|
|
uRot = false;
|
|
break;
|
|
case Keys.Down:
|
|
dRot = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|