CodeWalker/Forms/YtdForm.cs

395 lines
12 KiB
C#
Raw Normal View History

2017-09-21 18:33:05 +08:00
using CodeWalker.GameFiles;
using CodeWalker.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
2018-01-12 18:38:49 +08:00
using System.IO;
2017-09-21 18:33:05 +08:00
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CodeWalker.Forms
{
public partial class YtdForm : Form
{
private string fileName;
private YtdFile Ytd { get; set; }
private TextureDictionary TexDict { get; set; }
2018-01-12 18:38:49 +08:00
private Texture CurrentTexture = null;
private float CurrentZoom = 0.0f; //1.0 = 100%, 0.0 = stretch
2018-03-17 05:12:04 +08:00
private new Point MouseDown;
private Boolean MouseIsHovering = false;
private Boolean CanZoom = true;
2017-09-21 18:33:05 +08:00
public YtdForm()
{
InitializeComponent();
}
public void LoadYtd(YtdFile ytd)
{
Ytd = ytd;
fileName = ytd?.Name;
if (string.IsNullOrEmpty(fileName))
{
fileName = ytd?.RpfFileEntry?.Name;
}
LoadTexDict(ytd.TextureDict, fileName);
}
public void LoadTexDict(TextureDictionary texdict, string filename)
{
TexDict = texdict;
fileName = filename;
TexturesListView.Items.Clear();
SelTexturePictureBox.Image = null;
SelTextureNameTextBox.Text = string.Empty;
SelTextureDimensionsLabel.Text = "-";
SelTextureMipLabel.Text = "0";
SelTextureMipTrackBar.Value = 0;
SelTextureMipTrackBar.Maximum = 0;
if (TexDict == null)
{
return;
}
if ((TexDict.Textures == null) || (TexDict.Textures.data_items == null)) return;
var texs = TexDict.Textures.data_items;
for (int i = 0; i < texs.Length; i++)
{
var tex = texs[i];
ListViewItem lvi = TexturesListView.Items.Add(tex.Name);
lvi.ToolTipText = tex.Name;
lvi.Tag = tex;
lvi.SubItems.Add(tex.Width.ToString() + " x " + tex.Height.ToString());
}
if (TexturesListView.Items.Count > 0)
{
TexturesListView.Items[0].Selected = true;
}
UpdateStatus(GetTexCountStr());
UpdateFormTitle();
}
private string GetTexCountStr()
{
var texs = TexDict?.Textures?.data_items;
if (texs == null) return "";
return texs.Length.ToString() + " texture" + ((texs.Length != 1) ? "s" : "");
}
private void ShowTextureMip(Texture tex, int mip, bool mipchange)
{
2018-01-12 18:38:49 +08:00
CurrentTexture = tex;
UpdateSaveAs();
2017-09-21 18:33:05 +08:00
if (tex == null)
{
SelTexturePictureBox.Image = null;
SelTextureNameTextBox.Text = string.Empty;
SelTextureDimensionsLabel.Text = "-";
SelTextureMipLabel.Text = "0";
SelTextureMipTrackBar.Value = 0;
SelTextureMipTrackBar.Maximum = 0;
DetailsPropertyGrid.SelectedObject = null;
UpdateStatus(GetTexCountStr());
return;
}
if (mipchange)
{
if (mip >= tex.Levels) mip = tex.Levels - 1;
}
else
{
SelTextureMipTrackBar.Maximum = tex.Levels - 1;
}
SelTextureNameTextBox.Text = tex.Name;
DetailsPropertyGrid.SelectedObject = tex;
try
{
int cmip = Math.Min(Math.Max(mip, 0), tex.Levels - 1);
byte[] pixels = DDSIO.GetPixels(tex, cmip);
int w = tex.Width >> cmip;
int h = tex.Height >> cmip;
Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
if (pixels != null)
{
var BoundsRect = new System.Drawing.Rectangle(0, 0, w, h);
BitmapData bmpData = bmp.LockBits(BoundsRect, ImageLockMode.WriteOnly, bmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * bmp.Height;
Marshal.Copy(pixels, 0, ptr, bytes);
bmp.UnlockBits(bmpData);
}
var dimstr = w.ToString() + " x " + h.ToString();
SelTexturePictureBox.Image = bmp;
SelTextureDimensionsLabel.Text = dimstr;
var str1 = GetTexCountStr();
var str2 = tex.Name + ", mip " + cmip.ToString() + ", " + dimstr;
if (!string.IsNullOrEmpty(str1))
{
UpdateStatus(str1 + ". " + str2);
}
else
{
UpdateStatus(str2);
}
}
catch (Exception ex)
{
UpdateStatus("Error reading texture mip: " + ex.ToString());
SelTexturePictureBox.Image = null;
}
2018-01-12 18:38:49 +08:00
UpdateZoom();
2017-09-21 18:33:05 +08:00
}
private void UpdateFormTitle()
{
Text = fileName + " - Texture Dictionary - CodeWalker by dexyfex";
}
private void UpdateStatus(string text)
{
StatusLabel.Text = text;
}
2018-03-17 05:12:04 +08:00
public void Pan(MouseEventArgs mouse)
2018-01-12 18:38:49 +08:00
{
2018-03-17 05:12:04 +08:00
if (mouse.Button == MouseButtons.Left)
{
Point mousePosNow = mouse.Location;
2018-01-12 18:38:49 +08:00
2018-03-17 05:12:04 +08:00
int deltaX = mousePosNow.X - MouseDown.X;
int deltaY = mousePosNow.Y - MouseDown.Y;
int newX = SelTexturePictureBox.Location.X + deltaX;
int newY = SelTexturePictureBox.Location.Y + deltaY;
2018-01-12 18:38:49 +08:00
2018-03-17 05:12:04 +08:00
SelTexturePictureBox.Location = new Point(newX, newY);
2018-01-12 18:38:49 +08:00
}
}
2018-03-17 05:12:04 +08:00
public void Zoom(MouseEventArgs mouse)
{
if (MouseIsHovering == true)
{
int newWidth = SelTexturePictureBox.Image.Width;
int newHeight = SelTexturePictureBox.Image.Height;
int newX = SelTexturePictureBox.Location.X;
int newY = SelTexturePictureBox.Location.Y;
2018-01-12 18:38:49 +08:00
2018-03-17 05:12:04 +08:00
if (mouse.Delta > 0f)
{
newWidth = SelTexturePictureBox.Size.Width + (SelTexturePictureBox.Size.Width / 10);
newHeight = SelTexturePictureBox.Size.Height + (SelTexturePictureBox.Size.Height / 10);
newX = SelTexturePictureBox.Location.X - ((SelTexturePictureBox.Size.Width / 10) / 2);
newY = SelTexturePictureBox.Location.Y - ((SelTexturePictureBox.Size.Height / 10) / 2);
}
2018-01-12 18:38:49 +08:00
2018-03-17 05:12:04 +08:00
else if (mouse.Delta < 0f)
{
newWidth = SelTexturePictureBox.Size.Width - (SelTexturePictureBox.Size.Width / 10);
newHeight = SelTexturePictureBox.Size.Height - (SelTexturePictureBox.Size.Height / 10);
newX = SelTexturePictureBox.Location.X + ((SelTexturePictureBox.Size.Width / 10) / 2);
newY = SelTexturePictureBox.Location.Y + ((SelTexturePictureBox.Size.Height / 10) / 2);
}
SelTexturePictureBox.Size = new Size(newWidth, newHeight);
SelTexturePictureBox.Location = new Point(newX, newY);
}
}
2018-01-12 18:38:49 +08:00
2018-03-17 05:12:04 +08:00
private void UpdateZoom()
{
SelTexturePictureBox.SizeMode = PictureBoxSizeMode.Zoom;
SelTexturePictureBox.Width = SelTexturePanel.Width - 2;
SelTexturePictureBox.Height = SelTexturePanel.Height - 2;
SelTexturePictureBox.Location = SelTexturePanel.Location;
}
2018-01-12 18:38:49 +08:00
private void UpdateSaveAs()
{
if (CurrentTexture == null)
{
FileSaveAsMenu.Text = "Save As...";
ToolbarSaveAsMenu.Text = "Save As...";
FileSaveAsMenu.Enabled = false;
ToolbarSaveAsMenu.Enabled = false;
}
else
{
string fname = CurrentTexture.Name + ".dds";
string sas = "Save " + fname + " As...";
FileSaveAsMenu.Text = sas;
ToolbarSaveAsMenu.Text = sas;
FileSaveAsMenu.Enabled = true;
ToolbarSaveAsMenu.Enabled = true;
}
}
private void SaveAs()
{
if (CurrentTexture == null) return;
string fname = CurrentTexture.Name + ".dds";
SaveFileDialog.FileName = fname;
if (SaveFileDialog.ShowDialog() != DialogResult.OK) return;
string fpath = SaveFileDialog.FileName;
byte[] dds = DDSIO.GetDDSFile(CurrentTexture);
File.WriteAllBytes(fpath, dds);
}
private void SaveAll()
{
if (TexDict?.Textures?.data_items == null) return;
if (FolderBrowserDialog.ShowDialog() != DialogResult.OK) return;
var folder = FolderBrowserDialog.SelectedPath;
foreach (var tex in TexDict.Textures.data_items)
{
byte[] dds = DDSIO.GetDDSFile(tex);
string bpath = folder + "\\" + tex.Name;
string fpath = bpath + ".dds";
int c = 1;
while (File.Exists(fpath))
{
fpath = bpath + "_Copy" + c.ToString() + ".dds";
c++;
}
File.WriteAllBytes(fpath, dds);
}
}
2017-09-21 18:33:05 +08:00
private void TexturesListView_SelectedIndexChanged(object sender, EventArgs e)
{
Texture tex = null;
if (TexturesListView.SelectedItems.Count == 1)
{
tex = TexturesListView.SelectedItems[0].Tag as Texture;
}
ShowTextureMip(tex, 0, false);
}
private void SelTextureMipTrackBar_Scroll(object sender, EventArgs e)
{
Texture tex = null;
if (TexturesListView.SelectedItems.Count == 1)
{
tex = TexturesListView.SelectedItems[0].Tag as Texture;
}
SelTextureMipLabel.Text = SelTextureMipTrackBar.Value.ToString();
ShowTextureMip(tex, SelTextureMipTrackBar.Value, true);
}
2018-01-12 18:38:49 +08:00
private void SelTextureZoomCombo_TextChanged(object sender, EventArgs e)
{
string s = SelTextureZoomCombo.Text;
if (s.EndsWith("%")) s = s.Substring(0, s.Length - 1);
float f;
if (!float.TryParse(s, out f))
{
CurrentZoom = 0.0f;
}
else
{
CurrentZoom = Math.Min(Math.Max(f, 0.0f), 5000.0f) * 0.01f;
}
UpdateZoom();
}
private void FileSaveAllMenu_Click(object sender, EventArgs e)
{
SaveAll();
}
private void FileSaveAsMenu_Click(object sender, EventArgs e)
{
SaveAs();
}
private void SaveButton_ButtonClick(object sender, EventArgs e)
{
SaveAs();
}
private void ToolbarSaveAsMenu_Click(object sender, EventArgs e)
{
SaveAs();
}
private void ToolbarSaveAllMenu_Click(object sender, EventArgs e)
{
SaveAll();
}
2018-03-17 05:12:04 +08:00
protected override void OnMouseWheel(MouseEventArgs e)
{
if (CanZoom == true)
{
Zoom(e);
}
}
private void SelTexturePictureBox_MouseMove(object sender, MouseEventArgs e)
{
Pan(e);
}
private void SelTexturePictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
MouseDown = e.Location;
CanZoom = false;
Cursor.Current = Cursors.SizeAll;
}
}
private void SelTexturePictureBox_MouseUp(object sender, MouseEventArgs e)
{
CanZoom = true;
Cursor.Current = Cursors.Arrow;
}
private void SelTexturePanel_MouseLeave(object sender, EventArgs e)
{
MouseIsHovering = false;
}
private void SelTexturePictureBox_MouseEnter(object sender, EventArgs e)
{
MouseIsHovering = true;
}
2017-09-21 18:33:05 +08:00
}
}