diff --git a/T2Tools/Formats/EIBFile.cs b/T2Tools/Formats/EIBFile.cs
new file mode 100644
index 0000000..bfe2d36
--- /dev/null
+++ b/T2Tools/Formats/EIBFile.cs
@@ -0,0 +1,15 @@
+
+using System;
+
+namespace T2Tools.Formats
+{
+ class EIBFile
+ {
+ int a;
+
+ public EIBFile(byte[] data)
+ {
+ a = BitConverter.ToInt16(data, 0);
+ }
+ }
+}
diff --git a/T2Tools/MainForm.cs b/T2Tools/MainForm.cs
index 1a4f40d..d4ed4de 100644
--- a/T2Tools/MainForm.cs
+++ b/T2Tools/MainForm.cs
@@ -23,6 +23,7 @@ public partial class MainForm : Form
private int currentImgZoom = 3;
private MapMaker mapMaker;
+ private TilemapMaker tilemapMaker;
public MainForm()
{
@@ -43,7 +44,9 @@ private void MainForm_Load(object sender, EventArgs e)
{
MessageBox.Show("Failed to load game data: " + game.Error);
return;
- }
+ }
+
+ tilemapMaker = new TilemapMaker(game.Assets);
// fill TOC list
foreach (var entry in game.Assets.Entries.Values)
@@ -136,7 +139,7 @@ private void fileSelected(TOCListItem item)
case TOCEntryType.Tileset:
case TOCEntryType.CollisionInfo:
tilesCollisionsCheckbox.Checked = item.Entry.Type == TOCEntryType.CollisionInfo;
- Bitmap tilesetBitmap = makeTilesetBitmap(item.Entry);
+ Bitmap tilesetBitmap = tilemapMaker.MakeTilesetBitmap(item.Entry, tilesCollisionsCheckbox.Checked);
if (tilesetBitmap != null)
{
tilesPictureBox.Image = tilesetBitmap;
@@ -438,54 +441,9 @@ private void playSelectedTFM()
#endregion
#region tiles preview
- private Bitmap makeTilesetBitmap(TOCEntry entry)
- {
- string picName, palName, colName;
- TOCEntry picEntry, palEntry, colEntry;
-
- // level number from BLOCK?.PIC or WORLD?.COL file
- if (!int.TryParse(entry.Name.Substring(5, 1), out int levelNumber))
- return null;
- if (levelNumber == 6) levelNumber = 5;
-
- if (entry.Type == TOCEntryType.CollisionInfo) // get matching block?.pic
- {
- colEntry = entry;
- picName = $"BLOCK{levelNumber}.PIC";
- if (!game.Assets.Entries.ContainsKey(picName))
- return null;
- picEntry = game.Assets.Entries[picName];
- }
- else // get matching world?.col
- {
- picEntry = entry;
-
- // collision entry
- colName = $"WORLD{levelNumber}.COL";
- if (!game.Assets.Entries.ContainsKey(colName))
- return null;
- colEntry = game.Assets.Entries[colName];
- }
-
- // palette entry
- palName = $"WORLD{levelNumber}.PAL";
- if (!game.Assets.Entries.ContainsKey(palName))
- return null;
- palEntry = game.Assets.Entries[palName];
-
- // read col data
- COLFile colFile = tilesCollisionsCheckbox.Checked ? new COLFile(colEntry.Data) : null;
-
- try
- {
- return TilemapMaker.FromBitmaps(PICConverter.PICToBitmaps(picEntry.Data, palEntry.Data), colFile);
- }
- catch { return null; }
- }
-
private void tilesCollisionsCheckbox_CheckedChanged(object sender, EventArgs e)
{
- tilesPictureBox.Image = makeTilesetBitmap(selectedItem.Entry);
+ tilesPictureBox.Image = tilemapMaker.MakeTilesetBitmap(selectedItem.Entry, tilesCollisionsCheckbox.Checked);
}
#endregion
}
diff --git a/T2Tools/T2Tools.csproj b/T2Tools/T2Tools.csproj
index 888b8a5..ac89a01 100644
--- a/T2Tools/T2Tools.csproj
+++ b/T2Tools/T2Tools.csproj
@@ -56,6 +56,7 @@
+
diff --git a/T2Tools/Turrican/TOCEntry.cs b/T2Tools/Turrican/TOCEntry.cs
index a384a81..0daec19 100644
--- a/T2Tools/Turrican/TOCEntry.cs
+++ b/T2Tools/Turrican/TOCEntry.cs
@@ -5,7 +5,7 @@ namespace T2Tools.Turrican
{
public enum TOCEntryType { Unknown, Gap, Text, Language, StaticSprite, AnimatedSprite,
Tileset, Bitmap, PixelFont, TextmodeFont, Palette, EntitiesList,
- Music, Sound, Executable, Map, DAT, DIR, CollisionInfo }
+ Music, Sound, Executable, Map, DAT, DIR, CollisionInfo, BossSprite }
public class TOCEntry
{
@@ -41,6 +41,7 @@ public TOCEntryType Type
case ".gap": return TOCEntryType.Gap;
case ".eib": return TOCEntryType.EntitiesList;
case ".col": return TOCEntryType.CollisionInfo;
+ case ".mc": return TOCEntryType.BossSprite;
default: return TOCEntryType.Unknown;
}
}
diff --git a/T2Tools/Turrican/TilemapMaker.cs b/T2Tools/Turrican/TilemapMaker.cs
index 5be787b..635341e 100644
--- a/T2Tools/Turrican/TilemapMaker.cs
+++ b/T2Tools/Turrican/TilemapMaker.cs
@@ -40,34 +40,35 @@ public static Bitmap FromBitmaps(Bitmap[] bitmaps, COLFile collisionInfo)
{
if (i < collisionInfo.Entries.Length)
{
- if (collisionInfo.Entries[i].A > 0)
+ var entry = collisionInfo.Entries[i];
+ if (entry.A > 0)
{
- brush.Color = colors[collisionInfo.Entries[i].A];
+ brush.Color = colors[entry.A];
gfx.FillRectangle(brush, 16 * x, 16 * y, 8, 8);
}
- if (collisionInfo.Entries[i].B > 0)
+ if (entry.B > 0)
{
- brush.Color = colors[collisionInfo.Entries[i].B];
+ brush.Color = colors[entry.B];
gfx.FillRectangle(brush, 16 * x + 8, 16 * y, 8, 8);
}
- if (collisionInfo.Entries[i].C > 0)
+ if (entry.C > 0)
{
- brush.Color = colors[collisionInfo.Entries[i].C];
+ brush.Color = colors[entry.C];
gfx.FillRectangle(brush, 16 * x, 16 * y + 8, 8, 8);
}
- if (collisionInfo.Entries[i].D > 0)
+ if (entry.D > 0)
{
- brush.Color = colors[collisionInfo.Entries[i].D];
+ brush.Color = colors[entry.D];
gfx.FillRectangle(brush, 16 * x + 8, 16 * y + 8, 8, 8);
}
}
else
{
gfx.DrawLine(Pens.Red, 16 * x + 2, 16 * y + 2, 16 * x + 14, 16 * y + 14);
- gfx.DrawLine(Pens.Red, 16 * x + 14, 16 * y + 2, 16 * x + 2, 16 * y + 14);
+ gfx.DrawLine(Pens.Red, 16 * x + 14, 16 * y + 2, 16 * x + 2, 16 * y + 14);
}
}
}
@@ -75,5 +76,58 @@ public static Bitmap FromBitmaps(Bitmap[] bitmaps, COLFile collisionInfo)
return bmp;
}
+
+ private TOC assets;
+
+ public TilemapMaker(TOC assets)
+ {
+ this.assets = assets;
+ }
+
+ public Bitmap MakeTilesetBitmap(TOCEntry entry, bool collisions) // entry can be COL or PIC
+ {
+ string picName, palName, colName;
+ TOCEntry picEntry, palEntry, colEntry;
+
+ // level number from BLOCK?.PIC or WORLD?.COL file
+ if (!int.TryParse(entry.Name.Substring(5, 1), out int levelNumber))
+ return null;
+ if (levelNumber == 6) levelNumber = 5;
+
+ if (entry.Type == TOCEntryType.CollisionInfo) // get matching block?.pic
+ {
+ colEntry = entry;
+ picName = $"BLOCK{levelNumber}.PIC";
+ if (!assets.Entries.ContainsKey(picName))
+ return null;
+ picEntry = assets.Entries[picName];
+ }
+ else // get matching world?.col
+ {
+ picEntry = entry;
+
+ // collision entry
+ colName = $"WORLD{levelNumber}.COL";
+ if (!assets.Entries.ContainsKey(colName))
+ return null;
+ colEntry = assets.Entries[colName];
+ }
+
+ // palette entry
+ palName = $"WORLD{levelNumber}.PAL";
+ if (!assets.Entries.ContainsKey(palName))
+ return null;
+ palEntry = assets.Entries[palName];
+
+ // read col data
+ COLFile colFile = collisions ? new COLFile(colEntry.Data) : null;
+
+ try
+ {
+ return FromBitmaps(PICConverter.PICToBitmaps(picEntry.Data, palEntry.Data), colFile);
+ }
+ catch { return null; }
+ }
+
}
}
diff --git a/T2Tools/Utils/Extensions.cs b/T2Tools/Utils/Extensions.cs
index 276f9e2..78dc1f6 100644
--- a/T2Tools/Utils/Extensions.cs
+++ b/T2Tools/Utils/Extensions.cs
@@ -34,5 +34,17 @@ public static void FillCircle(this Graphics g, Brush brush,
radius + radius, radius + radius);
}
+ public static void InvokeIfRequired(this Control control, MethodInvoker action)
+ {
+ if (control.InvokeRequired)
+ {
+ control.Invoke(action);
+ }
+ else
+ {
+ action();
+ }
+ }
+
}
}
diff --git a/TFXTool/Extensions.cs b/TFXTool/Extensions.cs
new file mode 100644
index 0000000..a74a8a0
--- /dev/null
+++ b/TFXTool/Extensions.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Windows.Forms;
+
+namespace TFXTool
+{
+ public static class Extensions
+ {
+ public static void DoubleBuffered(this Control control, bool enable)
+ {
+ var doubleBufferPropertyInfo = control.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
+ doubleBufferPropertyInfo.SetValue(control, enable, null);
+ }
+
+ public static void InvokeIfRequired(this Control control, MethodInvoker action)
+ {
+ if (control.InvokeRequired)
+ {
+ control.Invoke(action);
+ }
+ else
+ {
+ action();
+ }
+ }
+
+ }
+}
diff --git a/TFXTool/PlayerForm.cs b/TFXTool/PlayerForm.cs
index 1cfbb8b..960f4d6 100644
--- a/TFXTool/PlayerForm.cs
+++ b/TFXTool/PlayerForm.cs
@@ -191,9 +191,10 @@ private void Playroutine_MacroStart(object sender, MacroStartEventArgs e)
private void Playroutine_TrackstepPositionChanged(object sender, EventArgs e)
{
- patternLabel.Text = "Pattern: " + currentPlayback.Playroutine.TrackstepPosition.ToString();
-
-
+ patternLabel.InvokeIfRequired(() =>
+ {
+ patternLabel.Text = "Pattern: " + currentPlayback.Playroutine.TrackstepPosition.ToString();
+ });
}
private void Playroutine_SongEnded(object sender, EventArgs e)
diff --git a/TFXTool/TFXTool.csproj b/TFXTool/TFXTool.csproj
index 2924f4e..a0e6001 100644
--- a/TFXTool/TFXTool.csproj
+++ b/TFXTool/TFXTool.csproj
@@ -51,6 +51,7 @@
+
Form