Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Iff 1.0 to Volcanic for SPR# Chunks #277

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions TSOClient/FSO.IDE/Common/SpriteEncoderUtils.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
using FSO.Files.Formats.IFF.Chunks;
using Microsoft.Xna.Framework;
using SimplePaletteQuantizer.Helpers;
using SimplePaletteQuantizer.Quantizers.DistinctSelection;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace FSO.IDE.Common
{
Expand Down Expand Up @@ -48,6 +54,16 @@ public static System.Drawing.Image[] GetPixelAlpha(SPR2Frame sprite, int tWidth,
{
return GetPixelAlpha(sprite, tWidth, tHeight, sprite.Position);
}
/// <summary>
/// Generates windows bitmaps for the appearance of this sprite.
/// </summary>
/// <param name="tWidth"></param>
/// <param name="tHeight"></param>
/// <returns>Array of three images, [Color, Alpha, Depth].</returns>
public static System.Drawing.Image[] GetPixelAlpha(SPRFrame sprite, int tWidth, int tHeight, bool DepthMapFrame = false)
{
return GetPixelAlpha(sprite, tWidth, tHeight, new Vector2(0), DepthMapFrame);
}

public static System.Drawing.Image[] GetPixelAlpha(SPR2Frame sprite, int tWidth, int tHeight, Vector2 pos)
{
Expand Down Expand Up @@ -108,6 +124,73 @@ public static System.Drawing.Image[] GetPixelAlpha(SPR2Frame sprite, int tWidth,
result[i].UnlockBits(locks[i]);
}

return result;
}
public static System.Drawing.Image[] GetPixelAlpha(SPRFrame sprite, int tWidth, int tHeight, Vector2 pos, bool DepthMapFrame = false)
{
var grayScale = default(PALT);
if (DepthMapFrame) grayScale = PALT.Greyscale;

var result = new System.Drawing.Bitmap[3];
var locks = new BitmapData[3];
var data = new byte[3][];
for (int i = 0; i < 3; i++)
{
result[i] = new System.Drawing.Bitmap(tWidth, tHeight, PixelFormat.Format24bppRgb);
locks[i] = result[i].LockBits(new System.Drawing.Rectangle(0, 0, tWidth, tHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
data[i] = new byte[locks[i].Stride * locks[i].Height];
}

int index = 0;
for (int y = 0; y < tHeight; y++)
{
for (int x = 0; x < tWidth; x++)
{
Microsoft.Xna.Framework.Color col;
byte depth = 255;

if (x >= pos.X && x < pos.X + sprite.Width && y >= pos.Y && y < pos.Y + sprite.Height)
{
//SPR depth frames use a grayscale palette
if (DepthMapFrame)
{
// Read this frame as grayscale
byte colorIndex = sprite.Indices[(y * sprite.Width + x)];
if(colorIndex == 0) col = new Microsoft.Xna.Framework.Color(0xFF, 0xFF, 0x00, 0x00);
else col = grayScale.Colors[colorIndex];
}
else
{ // not depth frame read colors from palette
col = sprite.GetPixel((int)(x - pos.X), (int)(y - pos.Y));
if (col.A == 0) col = new Microsoft.Xna.Framework.Color(0xFF, 0xFF, 0x00, 0x00);
// ** no alpha component!
}
}
else
{
col = new Microsoft.Xna.Framework.Color(0xFF, 0xFF, 0x00, 0x00);
}

data[0][index] = col.B;
data[0][index + 1] = col.G;
data[0][index + 2] = col.R;
data[0][index + 3] = 255;

data[1][index] = col.A;
data[1][index + 1] = col.A;
data[1][index + 2] = col.A;
data[1][index + 3] = 255;

index += 4;
}
}

for (int i = 0; i < 3; i++)
{
Marshal.Copy(data[i], 0, locks[i].Scan0, data[i].Length);
result[i].UnlockBits(locks[i]);
}

return result;
}
}
Expand Down
64 changes: 47 additions & 17 deletions TSOClient/FSO.IDE/MainWindow.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 44 additions & 21 deletions TSOClient/FSO.IDE/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using FSO.IDE.Common;
using FSO.IDE.ContentEditors;
using FSO.IDE.Managers;
using FSO.IDE.ResourceBrowser;
using FSO.IDE.Utils.FormatReverse;
using FSO.SimAntics;
using FSO.SimAntics.NetPlay.Model.Commands;
Expand Down Expand Up @@ -347,30 +348,52 @@ private void SaveFile(FileDialog dialog)
return;
}

private void openExternalIffToolStripMenuItem_Click(object sender, EventArgs e)
void ShowExternalIff(IffFile Iff = null, IffFile Spf = null, bool OBJDMode = false)
{
var dialog = new OpenFileDialog();
dialog.Title = "Select an iff file. (iff)";
SaveFile(dialog);
try
void Combine()
{
var iff = new IffFile(dialog.FileName);
iff.TSBO = true;
var obj = new GameObject();
obj.OBJ = iff.List<OBJD>()?.FirstOrDefault() ?? new OBJD();
obj.GUID = obj.OBJ.GUID;

//var res = new GameObjectResource(iff, null, null, "what", Content.Content.Get());
var res = new GameObjectResource(iff, null, null, "what", Content.Content.Get());
var res2 = new GameGlobalResource(iff, null);
obj.Resource = res;

IffManager.OpenResourceWindow(res2, obj);
if (Iff == null || Spf == null)
return;
foreach (var chunk in Spf.ListAll())
Iff.AddChunk(chunk);
}
catch
{

}
if (Iff == null && Spf == null)
throw new Exception("There was no provided IffFile to ShowExternalIff");

Combine();

var obj = new GameObject();
obj.OBJ = (Iff ?? Spf).List<OBJD>()?.FirstOrDefault() ?? new OBJD();
obj.GUID = obj.OBJ.GUID;

//var res = new GameObjectResource(iff, null, null, "what", Content.Content.Get());
var res = new GameObjectResource(Iff, Spf, null, "what", Content.Content.Get());
var res2 = new GameGlobalResource(Iff ?? Spf, null);
obj.Resource = res;

IffManager.OpenResourceWindow(OBJDMode ? (GameIffResource)res : res2, obj);
}

private void openExternalIffToolStripMenuItem_Click(object sender, EventArgs e)
{
IffFile iff = ExternalIffSelectorDialog.OpenExternalIff(out _, false);
if (iff == null) return;
ShowExternalIff(iff);
}
private void sPFFileToolStripMenuItem_Click(object sender, EventArgs e)
{
IffFile spf = ExternalIffSelectorDialog.OpenExternalIff(out _,true);
if (spf == null) return;
ShowExternalIff(null, spf);
}
private void bothToolStripMenuItem_Click(object sender, EventArgs e)
{
ExternalIffSelectorDialog dialog = new ExternalIffSelectorDialog();
dialog.ShowDialog();
if (dialog.Selection < 1) return;
if (dialog.Spf == null && dialog.Iff == null) return;
ShowExternalIff(dialog.Iff, dialog.Spf, dialog.Selection == 1);
}

private void semiGlobalToolStripMenuItem_Click(object sender, EventArgs e)
Expand All @@ -395,7 +418,7 @@ private void fieldEncodingReverserToolStripMenuItem_Click(object sender, EventAr
var fe = new FieldEncodingFormatTracker();
fe.Show();
fe.StartWithOBJM();
}
}
}

public class ResChangeNode : TreeNode
Expand Down
5 changes: 4 additions & 1 deletion TSOClient/FSO.IDE/ResourceBrowser/IFFResComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public partial class IFFResComponent : UserControl
{ typeof(CTSS), typeof(STRResourceControl) },
{ typeof(TTAB), typeof(TTABResourceControl) },
{ typeof(SPR2), typeof(SPR2ResourceControl) },
{ typeof(SPR), typeof(SPRResourceControl) },
{ typeof(BCON), typeof(BCONResourceControl) },
{ typeof(SLOT), typeof(SLOTResourceControl) },
{ typeof(FCNS), typeof(STRResourceControl) },
Expand All @@ -43,6 +44,7 @@ public partial class IFFResComponent : UserControl
typeof(SLOT),
typeof(CTSS),
typeof(SPR2),
typeof(SPR),
typeof(FCNS),
typeof(OTFFile)
};
Expand All @@ -54,7 +56,8 @@ public partial class IFFResComponent : UserControl
"Constants",
"SLOTs",
"Catalog Strings",
"Sprites",
"Sprites (SPR2)",
"Sprites (SPR#)",
"Simulator Constants",
"Tuning (OTF)"
};
Expand Down
Loading
Loading