Merge pull request #3192 from Mailaender/asset-browser
Created an Asset Browser to view and convert Sprites
This commit is contained in:
4
Makefile
4
Makefile
@@ -93,8 +93,8 @@ STD_MOD_DEPS = $(STD_MOD_LIBS) $(ralint_TARGET)
|
|||||||
mod_ra_SRCS := $(shell find OpenRA.Mods.RA/ -iname '*.cs')
|
mod_ra_SRCS := $(shell find OpenRA.Mods.RA/ -iname '*.cs')
|
||||||
mod_ra_TARGET = mods/ra/OpenRA.Mods.RA.dll
|
mod_ra_TARGET = mods/ra/OpenRA.Mods.RA.dll
|
||||||
mod_ra_KIND = library
|
mod_ra_KIND = library
|
||||||
mod_ra_DEPS = $(STD_MOD_DEPS)
|
mod_ra_DEPS = $(STD_MOD_DEPS) $(utility_TARGET)
|
||||||
mod_ra_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS)
|
mod_ra_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) $(utility_TARGET)
|
||||||
mod_ra_EXTRA_CMDS = mono --debug RALint.exe ra
|
mod_ra_EXTRA_CMDS = mono --debug RALint.exe ra
|
||||||
PROGRAMS += mod_ra
|
PROGRAMS += mod_ra
|
||||||
mod_ra: $(mod_ra_TARGET)
|
mod_ra: $(mod_ra_TARGET)
|
||||||
|
|||||||
@@ -18,19 +18,21 @@ namespace OpenRA.FileFormats
|
|||||||
{
|
{
|
||||||
public static class FileSystem
|
public static class FileSystem
|
||||||
{
|
{
|
||||||
static List<IFolder> mountedFolders = new List<IFolder>();
|
static List<IFolder> MountedFolders = new List<IFolder>();
|
||||||
|
|
||||||
static Cache<uint, List<IFolder>> allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
static Cache<uint, List<IFolder>> allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||||
|
|
||||||
|
public static List<string> FolderPaths = new List<string>();
|
||||||
|
|
||||||
static void MountInner(IFolder folder)
|
static void MountInner(IFolder folder)
|
||||||
{
|
{
|
||||||
mountedFolders.Add(folder);
|
MountedFolders.Add(folder);
|
||||||
|
|
||||||
foreach( var hash in folder.AllFileHashes() )
|
foreach (var hash in folder.AllFileHashes())
|
||||||
{
|
{
|
||||||
var l = allFiles[hash];
|
var l = allFiles[hash];
|
||||||
if( !l.Contains( folder ) )
|
if (!l.Contains(folder))
|
||||||
l.Add( folder );
|
l.Add(folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +80,9 @@ namespace OpenRA.FileFormats
|
|||||||
if (name.StartsWith("^"))
|
if (name.StartsWith("^"))
|
||||||
name = Platform.SupportDir+name.Substring(1);
|
name = Platform.SupportDir+name.Substring(1);
|
||||||
|
|
||||||
|
if (Directory.Exists(name))
|
||||||
|
FolderPaths.Add(name);
|
||||||
|
|
||||||
var a = (Action)(() => FileSystem.MountInner(OpenPackage(name)));
|
var a = (Action)(() => FileSystem.MountInner(OpenPackage(name)));
|
||||||
|
|
||||||
if (optional)
|
if (optional)
|
||||||
@@ -89,28 +94,29 @@ namespace OpenRA.FileFormats
|
|||||||
|
|
||||||
public static void UnmountAll()
|
public static void UnmountAll()
|
||||||
{
|
{
|
||||||
mountedFolders.Clear();
|
MountedFolders.Clear();
|
||||||
|
FolderPaths.Clear();
|
||||||
allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Unmount(IFolder mount)
|
public static bool Unmount(IFolder mount)
|
||||||
{
|
{
|
||||||
return (mountedFolders.RemoveAll(f => f == mount) > 0);
|
return (MountedFolders.RemoveAll(f => f == mount) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Mount(IFolder mount)
|
public static void Mount(IFolder mount)
|
||||||
{
|
{
|
||||||
if (!mountedFolders.Contains(mount)) mountedFolders.Add(mount);
|
if (!MountedFolders.Contains(mount)) MountedFolders.Add(mount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadFromManifest( Manifest manifest )
|
public static void LoadFromManifest(Manifest manifest)
|
||||||
{
|
{
|
||||||
UnmountAll();
|
UnmountAll();
|
||||||
foreach (var dir in manifest.Folders) Mount(dir);
|
foreach (var dir in manifest.Folders) Mount(dir);
|
||||||
foreach (var pkg in manifest.Packages) Mount(pkg);
|
foreach (var pkg in manifest.Packages) Mount(pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Stream GetFromCache( Cache<uint, List<IFolder>> index, string filename )
|
static Stream GetFromCache(Cache<uint, List<IFolder>> index, string filename)
|
||||||
{
|
{
|
||||||
var folder = index[PackageEntry.HashFilename(filename)]
|
var folder = index[PackageEntry.HashFilename(filename)]
|
||||||
.Where(x => x.Exists(filename))
|
.Where(x => x.Exists(filename))
|
||||||
@@ -125,21 +131,21 @@ namespace OpenRA.FileFormats
|
|||||||
|
|
||||||
public static Stream Open(string filename) { return OpenWithExts(filename, ""); }
|
public static Stream Open(string filename) { return OpenWithExts(filename, ""); }
|
||||||
|
|
||||||
public static Stream OpenWithExts( string filename, params string[] exts )
|
public static Stream OpenWithExts(string filename, params string[] exts)
|
||||||
{
|
{
|
||||||
if( filename.IndexOfAny( new char[] { '/', '\\' } ) == -1 )
|
if( filename.IndexOfAny( new char[] { '/', '\\' } ) == -1 )
|
||||||
{
|
{
|
||||||
foreach( var ext in exts )
|
foreach( var ext in exts )
|
||||||
{
|
{
|
||||||
var s = GetFromCache( allFiles, filename + ext );
|
var s = GetFromCache(allFiles, filename + ext);
|
||||||
if( s != null )
|
if (s != null)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach( var ext in exts )
|
foreach (var ext in exts)
|
||||||
{
|
{
|
||||||
var folder = mountedFolders
|
var folder = MountedFolders
|
||||||
.Where(x => x.Exists(filename + ext))
|
.Where(x => x.Exists(filename + ext))
|
||||||
.OrderByDescending(x => x.Priority)
|
.OrderByDescending(x => x.Priority)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
@@ -151,7 +157,7 @@ namespace OpenRA.FileFormats
|
|||||||
throw new FileNotFoundException("File not found: {0}".F(filename), filename);
|
throw new FileNotFoundException("File not found: {0}".F(filename), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Exists(string filename) { return mountedFolders.Any(f => f.Exists(filename)); }
|
public static bool Exists(string filename) { return MountedFolders.Any(f => f.Exists(filename)); }
|
||||||
|
|
||||||
static Dictionary<string, Assembly> assemblyCache = new Dictionary<string, Assembly>();
|
static Dictionary<string, Assembly> assemblyCache = new Dictionary<string, Assembly>();
|
||||||
|
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ namespace OpenRA.FileFormats
|
|||||||
|
|
||||||
int recurseDepth = 0;
|
int recurseDepth = 0;
|
||||||
|
|
||||||
public ShpReader( Stream stream )
|
public ShpReader(Stream stream)
|
||||||
{
|
{
|
||||||
using( var reader = new BinaryReader( stream ) )
|
using (var reader = new BinaryReader(stream))
|
||||||
{
|
{
|
||||||
ImageCount = reader.ReadUInt16();
|
ImageCount = reader.ReadUInt16();
|
||||||
reader.ReadUInt16();
|
reader.ReadUInt16();
|
||||||
@@ -73,60 +73,60 @@ namespace OpenRA.FileFormats
|
|||||||
Height = reader.ReadUInt16();
|
Height = reader.ReadUInt16();
|
||||||
reader.ReadUInt32();
|
reader.ReadUInt32();
|
||||||
|
|
||||||
for( int i = 0 ; i < ImageCount ; i++ )
|
for (int i = 0 ; i < ImageCount ; i++)
|
||||||
headers.Add( new ImageHeader( reader ) );
|
headers.Add(new ImageHeader(reader));
|
||||||
|
|
||||||
new ImageHeader( reader ); // end-of-file header
|
new ImageHeader(reader); // end-of-file header
|
||||||
new ImageHeader( reader ); // all-zeroes header
|
new ImageHeader(reader); // all-zeroes header
|
||||||
|
|
||||||
var offsets = headers.ToDictionary(h => h.Offset, h =>h);
|
var offsets = headers.ToDictionary(h => h.Offset, h =>h);
|
||||||
|
|
||||||
for( int i = 0 ; i < ImageCount ; i++ )
|
for (int i = 0 ; i < ImageCount ; i++)
|
||||||
{
|
{
|
||||||
var h = headers[ i ];
|
var h = headers[ i ];
|
||||||
if( h.Format == Format.Format20 )
|
if (h.Format == Format.Format20)
|
||||||
h.RefImage = headers[ i - 1 ];
|
h.RefImage = headers[i - 1];
|
||||||
|
|
||||||
else if( h.Format == Format.Format40 )
|
else if (h.Format == Format.Format40)
|
||||||
if( !offsets.TryGetValue( h.RefOffset, out h.RefImage ) )
|
if (!offsets.TryGetValue(h.RefOffset, out h.RefImage))
|
||||||
throw new InvalidDataException( "Reference doesnt point to image data {0}->{1}".F(h.Offset, h.RefOffset) );
|
throw new InvalidDataException("Reference doesnt point to image data {0}->{1}".F(h.Offset, h.RefOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach( ImageHeader h in headers )
|
foreach (ImageHeader h in headers)
|
||||||
Decompress( stream, h );
|
Decompress(stream, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageHeader this[ int index ]
|
public ImageHeader this[int index]
|
||||||
{
|
{
|
||||||
get { return headers[ index ]; }
|
get { return headers[index]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Decompress( Stream stream, ImageHeader h )
|
void Decompress(Stream stream, ImageHeader h)
|
||||||
{
|
{
|
||||||
if( recurseDepth > ImageCount )
|
if (recurseDepth > ImageCount)
|
||||||
throw new InvalidDataException( "Format20/40 headers contain infinite loop" );
|
throw new InvalidDataException("Format20/40 headers contain infinite loop");
|
||||||
|
|
||||||
switch( h.Format )
|
switch(h.Format)
|
||||||
{
|
{
|
||||||
case Format.Format20:
|
case Format.Format20:
|
||||||
case Format.Format40:
|
case Format.Format40:
|
||||||
{
|
{
|
||||||
if( h.RefImage.Image == null )
|
if (h.RefImage.Image == null)
|
||||||
{
|
{
|
||||||
++recurseDepth;
|
++recurseDepth;
|
||||||
Decompress( stream, h.RefImage );
|
Decompress(stream, h.RefImage);
|
||||||
--recurseDepth;
|
--recurseDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Image = CopyImageData( h.RefImage.Image );
|
h.Image = CopyImageData(h.RefImage.Image);
|
||||||
Format40.DecodeInto(ReadCompressedData(stream, h), h.Image);
|
Format40.DecodeInto(ReadCompressedData(stream, h), h.Image);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Format.Format80:
|
case Format.Format80:
|
||||||
{
|
{
|
||||||
var imageBytes = new byte[ Width * Height ];
|
var imageBytes = new byte[Width * Height];
|
||||||
Format80.DecodeInto( ReadCompressedData( stream, h ), imageBytes );
|
Format80.DecodeInto(ReadCompressedData(stream, h), imageBytes);
|
||||||
h.Image = imageBytes;
|
h.Image = imageBytes;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -135,11 +135,11 @@ namespace OpenRA.FileFormats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] ReadCompressedData( Stream stream, ImageHeader h )
|
static byte[] ReadCompressedData(Stream stream, ImageHeader h)
|
||||||
{
|
{
|
||||||
stream.Position = h.Offset;
|
stream.Position = h.Offset;
|
||||||
// Actually, far too big. There's no length field with the correct length though :(
|
// TODO: Actually, far too big. There's no length field with the correct length though :(
|
||||||
var compressedLength = (int)( stream.Length - stream.Position );
|
var compressedLength = (int)(stream.Length - stream.Position);
|
||||||
|
|
||||||
var compressedBytes = new byte[ compressedLength ];
|
var compressedBytes = new byte[ compressedLength ];
|
||||||
stream.Read( compressedBytes, 0, compressedLength );
|
stream.Read( compressedBytes, 0, compressedLength );
|
||||||
@@ -147,11 +147,11 @@ namespace OpenRA.FileFormats
|
|||||||
return compressedBytes;
|
return compressedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] CopyImageData( byte[] baseImage )
|
byte[] CopyImageData(byte[] baseImage)
|
||||||
{
|
{
|
||||||
var imageData = new byte[ Width * Height ];
|
var imageData = new byte[Width * Height];
|
||||||
for( int i = 0 ; i < Width * Height ; i++ )
|
for (int i = 0 ; i < Width * Height ; i++)
|
||||||
imageData[ i ] = baseImage[ i ];
|
imageData[i] = baseImage[i];
|
||||||
|
|
||||||
return imageData;
|
return imageData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace OpenRA.FileFormats
|
namespace OpenRA.FileFormats
|
||||||
@@ -20,7 +21,8 @@ namespace OpenRA.FileFormats
|
|||||||
public readonly string[]
|
public readonly string[]
|
||||||
Mods, Folders, Packages, Rules, ServerTraits,
|
Mods, Folders, Packages, Rules, ServerTraits,
|
||||||
Sequences, Cursors, Chrome, Assemblies, ChromeLayout,
|
Sequences, Cursors, Chrome, Assemblies, ChromeLayout,
|
||||||
Weapons, Voices, Notifications, Music, Movies, TileSets, ChromeMetrics;
|
Weapons, Voices, Notifications, Music, Movies, TileSets,
|
||||||
|
ChromeMetrics, PackageContents;
|
||||||
public readonly MiniYaml LoadScreen;
|
public readonly MiniYaml LoadScreen;
|
||||||
public readonly Dictionary<string, Pair<string,int>> Fonts;
|
public readonly Dictionary<string, Pair<string,int>> Fonts;
|
||||||
public readonly int TileSize = 24;
|
public readonly int TileSize = 24;
|
||||||
@@ -29,7 +31,7 @@ namespace OpenRA.FileFormats
|
|||||||
{
|
{
|
||||||
Mods = mods;
|
Mods = mods;
|
||||||
var yaml = new MiniYaml(null, mods
|
var yaml = new MiniYaml(null, mods
|
||||||
.Select(m => MiniYaml.FromFile("mods/" + m + "/mod.yaml"))
|
.Select(m => MiniYaml.FromFile("mods{0}{1}{0}mod.yaml".F(Path.DirectorySeparatorChar, m)))
|
||||||
.Aggregate(MiniYaml.MergeLiberal)).NodesDict;
|
.Aggregate(MiniYaml.MergeLiberal)).NodesDict;
|
||||||
|
|
||||||
// TODO: Use fieldloader
|
// TODO: Use fieldloader
|
||||||
@@ -49,6 +51,7 @@ namespace OpenRA.FileFormats
|
|||||||
Movies = YamlList(yaml, "Movies");
|
Movies = YamlList(yaml, "Movies");
|
||||||
TileSets = YamlList(yaml, "TileSets");
|
TileSets = YamlList(yaml, "TileSets");
|
||||||
ChromeMetrics = YamlList(yaml, "ChromeMetrics");
|
ChromeMetrics = YamlList(yaml, "ChromeMetrics");
|
||||||
|
PackageContents = YamlList(yaml, "PackageContents");
|
||||||
|
|
||||||
LoadScreen = yaml["LoadScreen"];
|
LoadScreen = yaml["LoadScreen"];
|
||||||
Fonts = yaml["Fonts"].NodesDict.ToDictionary(x => x.Key,
|
Fonts = yaml["Fonts"].NodesDict.ToDictionary(x => x.Key,
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
public static Dictionary<String, Mod> CurrentMods
|
public static Dictionary<String, Mod> CurrentMods
|
||||||
{
|
{
|
||||||
get { return Mod.AllMods.Where( k => modData.Manifest.Mods.Contains( k.Key )).ToDictionary( k => k.Key, k => k.Value ); }
|
get { return Mod.AllMods.Where(k => modData.Manifest.Mods.Contains(k.Key)).ToDictionary(k => k.Key, k => k.Value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
static Modifiers modifiers;
|
static Modifiers modifiers;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace OpenRA
|
|||||||
public static Dictionary<string, MusicInfo> Music;
|
public static Dictionary<string, MusicInfo> Music;
|
||||||
public static Dictionary<string, string> Movies;
|
public static Dictionary<string, string> Movies;
|
||||||
public static Dictionary<string, TileSet> TileSets;
|
public static Dictionary<string, TileSet> TileSets;
|
||||||
|
public static Dictionary<string, string> PackageContents;
|
||||||
|
|
||||||
public static void LoadRules(Manifest m, Map map)
|
public static void LoadRules(Manifest m, Map map)
|
||||||
{
|
{
|
||||||
@@ -35,6 +36,7 @@ namespace OpenRA
|
|||||||
Notifications = LoadYamlRules(m.Notifications, map.Notifications, (k, _) => new SoundInfo(k.Value));
|
Notifications = LoadYamlRules(m.Notifications, map.Notifications, (k, _) => new SoundInfo(k.Value));
|
||||||
Music = LoadYamlRules(m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
Music = LoadYamlRules(m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
||||||
Movies = LoadYamlRules(m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
Movies = LoadYamlRules(m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
||||||
|
PackageContents = LoadYamlRules(m.PackageContents, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
||||||
|
|
||||||
TileSets = new Dictionary<string, TileSet>();
|
TileSets = new Dictionary<string, TileSet>();
|
||||||
foreach (var file in m.TileSets)
|
foreach (var file in m.TileSets)
|
||||||
@@ -46,7 +48,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
static Dictionary<string, T> LoadYamlRules<T>(string[] files, List<MiniYamlNode> dict, Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
|
static Dictionary<string, T> LoadYamlRules<T>(string[] files, List<MiniYamlNode> dict, Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
|
||||||
{
|
{
|
||||||
var y = files.Select(a => MiniYaml.FromFile(a)).Aggregate(dict,MiniYaml.MergeLiberal);
|
var y = files.Select(a => MiniYaml.FromFile(a)).Aggregate(dict, MiniYaml.MergeLiberal);
|
||||||
var yy = y.ToDictionary( x => x.Key, x => x.Value );
|
var yy = y.ToDictionary( x => x.Key, x => x.Value );
|
||||||
return y.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => f(kv, yy));
|
return y.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => f(kv, yy));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
public class SpriteLoader
|
public class SpriteLoader
|
||||||
{
|
{
|
||||||
public SpriteLoader( string[] exts, SheetBuilder sheetBuilder )
|
public SpriteLoader(string[] exts, SheetBuilder sheetBuilder)
|
||||||
{
|
{
|
||||||
SheetBuilder = sheetBuilder;
|
SheetBuilder = sheetBuilder;
|
||||||
this.exts = exts;
|
this.exts = exts;
|
||||||
sprites = new Cache<string, Sprite[]>( LoadSprites );
|
sprites = new Cache<string, Sprite[]>(LoadSprites);
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly SheetBuilder SheetBuilder;
|
readonly SheetBuilder SheetBuilder;
|
||||||
|
|||||||
@@ -29,14 +29,14 @@ namespace OpenRA
|
|||||||
public SheetBuilder SheetBuilder;
|
public SheetBuilder SheetBuilder;
|
||||||
public SpriteLoader SpriteLoader;
|
public SpriteLoader SpriteLoader;
|
||||||
|
|
||||||
public ModData( params string[] mods )
|
public ModData(params string[] mods)
|
||||||
{
|
{
|
||||||
Manifest = new Manifest( mods );
|
Manifest = new Manifest(mods);
|
||||||
ObjectCreator = new ObjectCreator( Manifest );
|
ObjectCreator = new ObjectCreator(Manifest);
|
||||||
LoadScreen = ObjectCreator.CreateObject<ILoadScreen>(Manifest.LoadScreen.Value);
|
LoadScreen = ObjectCreator.CreateObject<ILoadScreen>(Manifest.LoadScreen.Value);
|
||||||
LoadScreen.Init(Manifest.LoadScreen.NodesDict.ToDictionary(x => x.Key, x => x.Value.Value));
|
LoadScreen.Init(Manifest.LoadScreen.NodesDict.ToDictionary(x => x.Key, x => x.Value.Value));
|
||||||
LoadScreen.Display();
|
LoadScreen.Display();
|
||||||
WidgetLoader = new WidgetLoader( this );
|
WidgetLoader = new WidgetLoader(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadInitialAssets(bool enumMaps)
|
public void LoadInitialAssets(bool enumMaps)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace OpenRA.Widgets
|
|||||||
public string Background = "scrollpanel-bg";
|
public string Background = "scrollpanel-bg";
|
||||||
public int ContentHeight = 0;
|
public int ContentHeight = 0;
|
||||||
public ILayout Layout;
|
public ILayout Layout;
|
||||||
|
public int MinimumThumbSize = 10;
|
||||||
protected float ListOffset = 0;
|
protected float ListOffset = 0;
|
||||||
protected bool UpPressed = false;
|
protected bool UpPressed = false;
|
||||||
protected bool DownPressed = false;
|
protected bool DownPressed = false;
|
||||||
@@ -79,7 +80,7 @@ namespace OpenRA.Widgets
|
|||||||
|
|
||||||
var ScrollbarHeight = rb.Height - 2 * ScrollbarWidth;
|
var ScrollbarHeight = rb.Height - 2 * ScrollbarWidth;
|
||||||
|
|
||||||
var thumbHeight = ContentHeight == 0 ? 0 : (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f));
|
var thumbHeight = ContentHeight == 0 ? 0 : Math.Max(MinimumThumbSize, (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f)));
|
||||||
var thumbOrigin = rb.Y + ScrollbarWidth + (int)((ScrollbarHeight - thumbHeight)*(-1f*ListOffset/(ContentHeight - rb.Height)));
|
var thumbOrigin = rb.Y + ScrollbarWidth + (int)((ScrollbarHeight - thumbHeight)*(-1f*ListOffset/(ContentHeight - rb.Height)));
|
||||||
if (thumbHeight == ScrollbarHeight)
|
if (thumbHeight == ScrollbarHeight)
|
||||||
thumbHeight = 0;
|
thumbHeight = 0;
|
||||||
@@ -206,7 +207,7 @@ namespace OpenRA.Widgets
|
|||||||
{
|
{
|
||||||
var rb = RenderBounds;
|
var rb = RenderBounds;
|
||||||
var ScrollbarHeight = rb.Height - 2 * ScrollbarWidth;
|
var ScrollbarHeight = rb.Height - 2 * ScrollbarWidth;
|
||||||
var thumbHeight = ContentHeight == 0 ? 0 : (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f));
|
var thumbHeight = ContentHeight == 0 ? 0 : Math.Max(MinimumThumbSize, (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f)));
|
||||||
var oldOffset = ListOffset;
|
var oldOffset = ListOffset;
|
||||||
ListOffset += (int)((lastMouseLocation.Y - mi.Location.Y)*(ContentHeight - rb.Height)*1f/(ScrollbarHeight - thumbHeight));
|
ListOffset += (int)((lastMouseLocation.Y - mi.Location.Y)*(ContentHeight - rb.Height)*1f/(ScrollbarHeight - thumbHeight));
|
||||||
ListOffset = Math.Min(0,Math.Max(rb.Height - ContentHeight, ListOffset));
|
ListOffset = Math.Min(0,Math.Max(rb.Height - ContentHeight, ListOffset));
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace OpenRA.Widgets
|
|||||||
public string Image = "";
|
public string Image = "";
|
||||||
public int Frame = 0;
|
public int Frame = 0;
|
||||||
public string Palette = "chrome";
|
public string Palette = "chrome";
|
||||||
|
public bool LoopAnimation = false;
|
||||||
|
|
||||||
public Func<string> GetImage;
|
public Func<string> GetImage;
|
||||||
public Func<int> GetFrame;
|
public Func<int> GetFrame;
|
||||||
@@ -26,12 +27,13 @@ namespace OpenRA.Widgets
|
|||||||
readonly WorldRenderer worldRenderer;
|
readonly WorldRenderer worldRenderer;
|
||||||
|
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
public ShpImageWidget( WorldRenderer worldRenderer)
|
public ShpImageWidget(WorldRenderer worldRenderer)
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
GetImage = () => { return Image; };
|
GetImage = () => { return Image; };
|
||||||
GetFrame = () => { return Frame; };
|
GetFrame = () => { return Frame; };
|
||||||
GetPalette = () => { return Palette; };
|
GetPalette = () => { return Palette; };
|
||||||
|
|
||||||
this.worldRenderer = worldRenderer;
|
this.worldRenderer = worldRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,9 +43,12 @@ namespace OpenRA.Widgets
|
|||||||
Image = other.Image;
|
Image = other.Image;
|
||||||
Frame = other.Frame;
|
Frame = other.Frame;
|
||||||
Palette = other.Palette;
|
Palette = other.Palette;
|
||||||
|
LoopAnimation = other.LoopAnimation;
|
||||||
|
|
||||||
GetImage = other.GetImage;
|
GetImage = other.GetImage;
|
||||||
GetFrame = other.GetFrame;
|
GetFrame = other.GetFrame;
|
||||||
GetPalette = other.GetPalette;
|
GetPalette = other.GetPalette;
|
||||||
|
|
||||||
worldRenderer = other.worldRenderer;
|
worldRenderer = other.worldRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,5 +73,32 @@ namespace OpenRA.Widgets
|
|||||||
|
|
||||||
Game.Renderer.SpriteRenderer.DrawSprite(sprite, RenderOrigin, worldRenderer, palette);
|
Game.Renderer.SpriteRenderer.DrawSprite(sprite, RenderOrigin, worldRenderer, palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int FrameCount
|
||||||
|
{
|
||||||
|
get { return Game.modData.SpriteLoader.LoadAllSprites(Image).Length-1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenderNextFrame()
|
||||||
|
{
|
||||||
|
if (Frame < FrameCount)
|
||||||
|
Frame++;
|
||||||
|
else
|
||||||
|
Frame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenderPreviousFrame()
|
||||||
|
{
|
||||||
|
if (Frame > 0)
|
||||||
|
Frame--;
|
||||||
|
else
|
||||||
|
Frame = FrameCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Tick()
|
||||||
|
{
|
||||||
|
if (LoopAnimation)
|
||||||
|
RenderNextFrame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,10 +24,15 @@ namespace OpenRA.Widgets
|
|||||||
public float MinimumValue = 0;
|
public float MinimumValue = 0;
|
||||||
public float MaximumValue = 1;
|
public float MaximumValue = 1;
|
||||||
public float Value = 0;
|
public float Value = 0;
|
||||||
|
public Func<float> GetValue;
|
||||||
|
|
||||||
protected bool isMoving = false;
|
protected bool isMoving = false;
|
||||||
|
|
||||||
public SliderWidget() : base() {}
|
public SliderWidget()
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
GetValue = () => Value;
|
||||||
|
}
|
||||||
|
|
||||||
public SliderWidget(SliderWidget other)
|
public SliderWidget(SliderWidget other)
|
||||||
: base(other)
|
: base(other)
|
||||||
@@ -38,6 +43,7 @@ namespace OpenRA.Widgets
|
|||||||
MaximumValue = other.MaximumValue;
|
MaximumValue = other.MaximumValue;
|
||||||
Value = other.Value;
|
Value = other.Value;
|
||||||
TrackHeight = other.TrackHeight;
|
TrackHeight = other.TrackHeight;
|
||||||
|
GetValue = other.GetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateValue(float newValue)
|
void UpdateValue(float newValue)
|
||||||
@@ -53,7 +59,7 @@ namespace OpenRA.Widgets
|
|||||||
if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) return false;
|
if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) return false;
|
||||||
if (!Focused) return false;
|
if (!Focused) return false;
|
||||||
|
|
||||||
switch( mi.Event )
|
switch(mi.Event)
|
||||||
{
|
{
|
||||||
case MouseInputEvent.Up:
|
case MouseInputEvent.Up:
|
||||||
isMoving = false;
|
isMoving = false;
|
||||||
@@ -99,6 +105,8 @@ namespace OpenRA.Widgets
|
|||||||
if (!IsVisible())
|
if (!IsVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Value = GetValue();
|
||||||
|
|
||||||
var tr = ThumbRect;
|
var tr = ThumbRect;
|
||||||
var rb = RenderBounds;
|
var rb = RenderBounds;
|
||||||
var trackWidth = rb.Width;
|
var trackWidth = rb.Width;
|
||||||
|
|||||||
@@ -227,6 +227,12 @@ namespace OpenRA.Widgets
|
|||||||
return Mod.AllMods[mod].Title;
|
return Mod.AllMods[mod].Title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ActiveModId()
|
||||||
|
{
|
||||||
|
var mod = Game.modData.Manifest.Mods[0];
|
||||||
|
return Mod.AllMods[mod].Id;
|
||||||
|
}
|
||||||
|
|
||||||
public static string ChooseInitialMap(string map)
|
public static string ChooseInitialMap(string map)
|
||||||
{
|
{
|
||||||
var availableMaps = Game.modData.AvailableMaps;
|
var availableMaps = Game.modData.AvailableMaps;
|
||||||
|
|||||||
@@ -436,6 +436,8 @@
|
|||||||
<Compile Include="Widgets\ColorMixerWidget.cs" />
|
<Compile Include="Widgets\ColorMixerWidget.cs" />
|
||||||
<Compile Include="Widgets\HueSliderWidget.cs" />
|
<Compile Include="Widgets\HueSliderWidget.cs" />
|
||||||
<Compile Include="Render\WithTurret.cs" />
|
<Compile Include="Render\WithTurret.cs" />
|
||||||
|
<Compile Include="Widgets\Logic\AssetBrowserLogic.cs" />
|
||||||
|
<Compile Include="Widgets\Logic\ConvertGameFilesLogic.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||||
@@ -448,6 +450,10 @@
|
|||||||
<Name>OpenRA.Game</Name>
|
<Name>OpenRA.Game</Name>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\OpenRA.Utility\OpenRA.Utility.csproj">
|
||||||
|
<Project>{F33337BE-CB69-4B24-850F-07D23E408DDF}</Project>
|
||||||
|
<Name>OpenRA.Utility</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||||
|
|||||||
261
OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs
Normal file
261
OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation. For more information,
|
||||||
|
* see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.FileFormats;
|
||||||
|
using OpenRA.GameRules;
|
||||||
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.RA.Widgets.Logic
|
||||||
|
{
|
||||||
|
public class AssetBrowserLogic
|
||||||
|
{
|
||||||
|
Widget panel;
|
||||||
|
|
||||||
|
static ShpImageWidget spriteImage;
|
||||||
|
static TextFieldWidget filenameInput;
|
||||||
|
static SliderWidget frameSlider;
|
||||||
|
static ButtonWidget playButton, pauseButton;
|
||||||
|
static ScrollPanelWidget assetList;
|
||||||
|
static ScrollItemWidget template;
|
||||||
|
|
||||||
|
public enum SourceType { Folders, Packages }
|
||||||
|
public static SourceType AssetSource = SourceType.Folders;
|
||||||
|
|
||||||
|
public static List<string> AvailableShps = new List<string>();
|
||||||
|
|
||||||
|
[ObjectCreator.UseCtor]
|
||||||
|
public AssetBrowserLogic(Widget widget, Action onExit, World world)
|
||||||
|
{
|
||||||
|
panel = widget;
|
||||||
|
|
||||||
|
var sourceDropdown = panel.Get<DropDownButtonWidget>("SOURCE_SELECTOR");
|
||||||
|
sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
|
||||||
|
sourceDropdown.GetText = () => AssetSource == SourceType.Folders ? "Folders"
|
||||||
|
: AssetSource == SourceType.Packages ? "Packages" : "None";
|
||||||
|
sourceDropdown.Disabled = !Rules.PackageContents.Keys.Any();
|
||||||
|
|
||||||
|
spriteImage = panel.Get<ShpImageWidget>("SPRITE");
|
||||||
|
|
||||||
|
filenameInput = panel.Get<TextFieldWidget>("FILENAME_INPUT");
|
||||||
|
filenameInput.Text = spriteImage.Image+".shp";
|
||||||
|
filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text);
|
||||||
|
|
||||||
|
frameSlider = panel.Get<SliderWidget>("FRAME_SLIDER");
|
||||||
|
frameSlider.MaximumValue = (float)spriteImage.FrameCount;
|
||||||
|
frameSlider.Ticks = spriteImage.FrameCount+1;
|
||||||
|
frameSlider.OnChange += x => { spriteImage.Frame = (int)Math.Round(x); };
|
||||||
|
frameSlider.GetValue = () => spriteImage.Frame;
|
||||||
|
|
||||||
|
panel.Get<LabelWidget>("FRAME_COUNT").GetText = () => "{0}/{1}".F(spriteImage.Frame, spriteImage.FrameCount);
|
||||||
|
|
||||||
|
playButton = panel.Get<ButtonWidget>("BUTTON_PLAY");
|
||||||
|
playButton.OnClick = () =>
|
||||||
|
{
|
||||||
|
spriteImage.LoopAnimation = true;
|
||||||
|
playButton.Visible = false;
|
||||||
|
pauseButton.Visible = true;
|
||||||
|
};
|
||||||
|
pauseButton = panel.Get<ButtonWidget>("BUTTON_PAUSE");
|
||||||
|
pauseButton.OnClick = () =>
|
||||||
|
{
|
||||||
|
spriteImage.LoopAnimation = false;
|
||||||
|
playButton.Visible = true;
|
||||||
|
pauseButton.Visible = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
panel.Get<ButtonWidget>("BUTTON_STOP").OnClick = () =>
|
||||||
|
{
|
||||||
|
spriteImage.LoopAnimation = false;
|
||||||
|
frameSlider.Value = 0;
|
||||||
|
spriteImage.Frame = 0;
|
||||||
|
playButton.Visible = true;
|
||||||
|
pauseButton.Visible = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
panel.Get<ButtonWidget>("BUTTON_NEXT").OnClick = () => { spriteImage.RenderNextFrame(); };
|
||||||
|
panel.Get<ButtonWidget>("BUTTON_PREV").OnClick = () => { spriteImage.RenderPreviousFrame(); };
|
||||||
|
|
||||||
|
panel.Get<ButtonWidget>("LOAD_BUTTON").OnClick = () =>
|
||||||
|
{
|
||||||
|
LoadAsset(filenameInput.Text);
|
||||||
|
};
|
||||||
|
|
||||||
|
assetList = panel.Get<ScrollPanelWidget>("ASSET_LIST");
|
||||||
|
template = panel.Get<ScrollItemWidget>("ASSET_TEMPLATE");
|
||||||
|
PopulateAssetList();
|
||||||
|
|
||||||
|
var palette = (WidgetUtils.ActiveModId() == "d2k") ? "d2k.pal" : "egopal.pal";
|
||||||
|
|
||||||
|
panel.Get<ButtonWidget>("EXPORT_BUTTON").OnClick = () =>
|
||||||
|
{
|
||||||
|
var ExtractGameFiles = new string[][]
|
||||||
|
{
|
||||||
|
new string[] {"--extract", WidgetUtils.ActiveModId(), palette, "--userdir"},
|
||||||
|
new string[] {"--extract", WidgetUtils.ActiveModId(), "{0}.shp".F(spriteImage.Image), "--userdir"},
|
||||||
|
};
|
||||||
|
|
||||||
|
var ExportToPng = new string[][]
|
||||||
|
{
|
||||||
|
new string[] {"--png", Platform.SupportDir+"{0}.shp".F(spriteImage.Image), Platform.SupportDir+palette},
|
||||||
|
};
|
||||||
|
|
||||||
|
var ImportFromPng = new string[][] { };
|
||||||
|
|
||||||
|
var args = new WidgetArgs()
|
||||||
|
{
|
||||||
|
{ "ExtractGameFiles", ExtractGameFiles },
|
||||||
|
{ "ExportToPng", ExportToPng },
|
||||||
|
{ "ImportFromPng", ImportFromPng}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ui.OpenWindow("CONVERT_ASSETS_PANEL", args);
|
||||||
|
};
|
||||||
|
|
||||||
|
panel.Get<ButtonWidget>("EXTRACT_BUTTON").OnClick = () =>
|
||||||
|
{
|
||||||
|
var ExtractGameFilesList = new List<string[]>();
|
||||||
|
var ExportToPngList = new List<string[]>();
|
||||||
|
|
||||||
|
ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette, "--userdir"} );
|
||||||
|
|
||||||
|
foreach (var shp in AvailableShps)
|
||||||
|
{
|
||||||
|
ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), shp, "--userdir" } );
|
||||||
|
ExportToPngList.Add(new string[] { "--png", Platform.SupportDir+shp, Platform.SupportDir+palette } );
|
||||||
|
Console.WriteLine(Platform.SupportDir+shp);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ExtractGameFiles = ExtractGameFilesList.ToArray();
|
||||||
|
var ExportToPng = ExportToPngList.ToArray();
|
||||||
|
var ImportFromPng = new string[][] { };
|
||||||
|
|
||||||
|
var args = new WidgetArgs()
|
||||||
|
{
|
||||||
|
{ "ExtractGameFiles", ExtractGameFiles },
|
||||||
|
{ "ExportToPng", ExportToPng },
|
||||||
|
{ "ImportFromPng", ImportFromPng}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ui.OpenWindow("CONVERT_ASSETS_PANEL", args);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
panel.Get<ButtonWidget>("IMPORT_BUTTON").OnClick = () =>
|
||||||
|
{
|
||||||
|
var imageSizeInput = panel.Get<TextFieldWidget>("IMAGE_SIZE_INPUT");
|
||||||
|
var imageFilename = panel.Get<TextFieldWidget>("IMAGE_FILENAME_INPUT");
|
||||||
|
|
||||||
|
var ExtractGameFiles = new string[][] { };
|
||||||
|
var ExportToPng = new string[][] { };
|
||||||
|
var ImportFromPng = new string[][]
|
||||||
|
{
|
||||||
|
new string[] {"--shp", Platform.SupportDir+imageFilename.Text, imageSizeInput.Text},
|
||||||
|
};
|
||||||
|
|
||||||
|
var args = new WidgetArgs()
|
||||||
|
{
|
||||||
|
{ "ExtractGameFiles", ExtractGameFiles },
|
||||||
|
{ "ExportToPng", ExportToPng },
|
||||||
|
{ "ImportFromPng", ImportFromPng}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ui.OpenWindow("CONVERT_ASSETS_PANEL", args);
|
||||||
|
};
|
||||||
|
|
||||||
|
panel.Get<ButtonWidget>("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template)
|
||||||
|
{
|
||||||
|
var sprite = Path.GetFileNameWithoutExtension(filepath);
|
||||||
|
var filename = Path.GetFileName(filepath);
|
||||||
|
|
||||||
|
var item = ScrollItemWidget.Setup(template,
|
||||||
|
() => spriteImage != null && spriteImage.Image == sprite,
|
||||||
|
() => LoadAsset(sprite));
|
||||||
|
item.Get<LabelWidget>("TITLE").GetText = () => filename;
|
||||||
|
|
||||||
|
list.AddChild(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool LoadAsset(string sprite)
|
||||||
|
{
|
||||||
|
if (sprite == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!sprite.ToLower().Contains("r8"))
|
||||||
|
{
|
||||||
|
filenameInput.Text = sprite+".shp";
|
||||||
|
sprite = Path.GetFileNameWithoutExtension(sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
spriteImage.Frame = 0;
|
||||||
|
spriteImage.Image = sprite;
|
||||||
|
frameSlider.MaximumValue = (float)spriteImage.FrameCount;
|
||||||
|
frameSlider.Ticks = spriteImage.FrameCount+1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ShowSourceDropdown(DropDownButtonWidget dropdown)
|
||||||
|
{
|
||||||
|
var options = new Dictionary<string, SourceType>()
|
||||||
|
{
|
||||||
|
{ "Folders", SourceType.Folders },
|
||||||
|
{ "Packages", SourceType.Packages },
|
||||||
|
};
|
||||||
|
|
||||||
|
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
|
||||||
|
{
|
||||||
|
var item = ScrollItemWidget.Setup(itemTemplate,
|
||||||
|
() => AssetSource == options[o],
|
||||||
|
() => { AssetSource = options[o]; PopulateAssetList(); });
|
||||||
|
item.Get<LabelWidget>("LABEL").GetText = () => o;
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PopulateAssetList()
|
||||||
|
{
|
||||||
|
assetList.RemoveChildren();
|
||||||
|
AvailableShps.Clear();
|
||||||
|
|
||||||
|
if (AssetSource == SourceType.Folders)
|
||||||
|
{
|
||||||
|
foreach (var folder in FileSystem.FolderPaths)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
var shps = Directory.GetFiles(folder, "*.shp");
|
||||||
|
foreach (var shp in shps)
|
||||||
|
{
|
||||||
|
AddAsset(assetList, shp, template);
|
||||||
|
AvailableShps.Add(Path.GetFileName(shp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AssetSource == SourceType.Packages)
|
||||||
|
foreach (var hiddenFile in Rules.PackageContents.Keys)
|
||||||
|
{
|
||||||
|
AddAsset(assetList, hiddenFile, template);
|
||||||
|
AvailableShps.Add(hiddenFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
113
OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs
Normal file
113
OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation. For more information,
|
||||||
|
* see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using OpenRA.FileFormats;
|
||||||
|
using OpenRA.FileFormats.Graphics;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
using OpenRA.Utility;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.RA.Widgets.Logic
|
||||||
|
{
|
||||||
|
public class ConvertGameFilesLogic
|
||||||
|
{
|
||||||
|
Widget panel;
|
||||||
|
ProgressBarWidget progressBar;
|
||||||
|
LabelWidget statusLabel;
|
||||||
|
ButtonWidget retryButton, backButton;
|
||||||
|
Widget extractingContainer;
|
||||||
|
|
||||||
|
string[][] ExtractGameFiles, ExportToPng, ImportFromPng;
|
||||||
|
|
||||||
|
[ObjectCreator.UseCtor]
|
||||||
|
public ConvertGameFilesLogic(Widget widget, string[][] ExtractGameFiles, string[][] ExportToPng, string[][] ImportFromPng)
|
||||||
|
{
|
||||||
|
panel = widget.Get("CONVERT_ASSETS_PANEL");
|
||||||
|
progressBar = panel.Get<ProgressBarWidget>("PROGRESS_BAR");
|
||||||
|
statusLabel = panel.Get<LabelWidget>("STATUS_LABEL");
|
||||||
|
|
||||||
|
backButton = panel.Get<ButtonWidget>("BACK_BUTTON");
|
||||||
|
backButton.OnClick = Ui.CloseWindow;
|
||||||
|
|
||||||
|
retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
|
||||||
|
retryButton.OnClick = Extract;
|
||||||
|
|
||||||
|
extractingContainer = panel.Get("EXTRACTING");
|
||||||
|
|
||||||
|
this.ExtractGameFiles = ExtractGameFiles;
|
||||||
|
this.ExportToPng = ExportToPng;
|
||||||
|
this.ImportFromPng = ImportFromPng;
|
||||||
|
|
||||||
|
Extract();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Extract()
|
||||||
|
{
|
||||||
|
backButton.IsDisabled = () => true;
|
||||||
|
retryButton.IsDisabled = () => true;
|
||||||
|
extractingContainer.IsVisible = () => true;
|
||||||
|
|
||||||
|
var onError = (Action<string>)(s => Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
statusLabel.GetText = () => "Error: "+s;
|
||||||
|
backButton.IsDisabled = () => false;
|
||||||
|
retryButton.IsDisabled = () => false;
|
||||||
|
}));
|
||||||
|
|
||||||
|
var t = new Thread( _ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ExtractGameFiles.Length; i++)
|
||||||
|
{
|
||||||
|
progressBar.Percentage = i*100/ExtractGameFiles.Count();
|
||||||
|
statusLabel.GetText = () => "Extracting...";
|
||||||
|
Utility.Command.ExtractFiles(ExtractGameFiles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ExportToPng.Length; i++)
|
||||||
|
{
|
||||||
|
progressBar.Percentage = i*100/ExportToPng.Count();
|
||||||
|
statusLabel.GetText = () => "Exporting SHP to PNG...";
|
||||||
|
Utility.Command.ConvertShpToPng(ExportToPng[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ImportFromPng.Length; i++)
|
||||||
|
{
|
||||||
|
progressBar.Percentage = i*100/ImportFromPng.Count();
|
||||||
|
statusLabel.GetText = () => "Converting PNG to SHP...";
|
||||||
|
Utility.Command.ConvertPngToShp(ImportFromPng[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
progressBar.Percentage = 100;
|
||||||
|
statusLabel.GetText = () => "Done. Check {0}".F(Platform.SupportDir);
|
||||||
|
backButton.IsDisabled = () => false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException f)
|
||||||
|
{
|
||||||
|
onError(f.FileName+" not found.");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
onError(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}) { IsBackground = true };
|
||||||
|
t.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||||
* This file is part of OpenRA, which is free software. It is made
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
* available to you under the terms of the GNU General Public License
|
* available to you under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation. For more information,
|
* as published by the Free Software Foundation. For more information,
|
||||||
@@ -14,7 +14,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
{
|
{
|
||||||
public class MainMenuButtonsLogic
|
public class MainMenuButtonsLogic
|
||||||
{
|
{
|
||||||
|
|
||||||
enum MenuType { Main, None }
|
enum MenuType { Main, None }
|
||||||
MenuType Menu = MenuType.Main;
|
MenuType Menu = MenuType.Main;
|
||||||
|
|
||||||
@@ -73,6 +72,15 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
widget.Get<ButtonWidget>("MAINMENU_BUTTON_ASSET_BROWSER").OnClick = () =>
|
||||||
|
{
|
||||||
|
Menu = MenuType.None;
|
||||||
|
Game.OpenWindow("ASSETBROWSER_BG", new WidgetArgs()
|
||||||
|
{
|
||||||
|
{ "onExit", () => Menu = MenuType.Main }
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
widget.Get<ButtonWidget>("MAINMENU_BUTTON_QUIT").OnClick = () => Game.Exit();
|
widget.Get<ButtonWidget>("MAINMENU_BUTTON_QUIT").OnClick = () => Game.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace OpenRA.Utility
|
|||||||
ShpWriter.Write(destStream, width, srcImage.Height,
|
ShpWriter.Write(destStream, width, srcImage.Height,
|
||||||
srcImage.ToFrames(width));
|
srcImage.ToFrames(width));
|
||||||
|
|
||||||
Console.WriteLine(dest+" saved");
|
Console.WriteLine(dest+" saved.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static IEnumerable<byte[]> ToFrames(this Bitmap bitmap, int width)
|
static IEnumerable<byte[]> ToFrames(this Bitmap bitmap, int width)
|
||||||
@@ -108,10 +108,11 @@ namespace OpenRA.Utility
|
|||||||
|
|
||||||
x += srcImage.Width;
|
x += srcImage.Width;
|
||||||
|
|
||||||
bitmap.UnlockBits( data );
|
bitmap.UnlockBits(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap.Save(dest);
|
bitmap.Save(dest);
|
||||||
|
Console.WriteLine(dest+" saved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,8 +349,8 @@ namespace OpenRA.Utility
|
|||||||
if (template.Value == null)
|
if (template.Value == null)
|
||||||
throw new InvalidOperationException("No such template '{0}'".F(templateName));
|
throw new InvalidOperationException("No such template '{0}'".F(templateName));
|
||||||
|
|
||||||
using( var image = tileset.RenderTemplate(template.Value.Id, palette) )
|
using (var image = tileset.RenderTemplate(template.Value.Id, palette))
|
||||||
image.Save( Path.ChangeExtension( templateName, ".png" ) );
|
image.Save(Path.ChangeExtension(templateName, ".png"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,17 +360,17 @@ namespace OpenRA.Utility
|
|||||||
var dest = args[2];
|
var dest = args[2];
|
||||||
|
|
||||||
Dune2ShpReader srcImage = null;
|
Dune2ShpReader srcImage = null;
|
||||||
using( var s = File.OpenRead( src ) )
|
using(var s = File.OpenRead(src))
|
||||||
srcImage = new Dune2ShpReader(s);
|
srcImage = new Dune2ShpReader(s);
|
||||||
|
|
||||||
var size = srcImage.First().Size;
|
var size = srcImage.First().Size;
|
||||||
|
|
||||||
if (!srcImage.All( im => im.Size == size ))
|
if (!srcImage.All(im => im.Size == size))
|
||||||
throw new InvalidOperationException("All the frames must be the same size to convert from Dune2 to RA");
|
throw new InvalidOperationException("All the frames must be the same size to convert from Dune2 to RA");
|
||||||
|
|
||||||
using( var destStream = File.Create(dest) )
|
using (var destStream = File.Create(dest))
|
||||||
ShpWriter.Write(destStream, size.Width, size.Height,
|
ShpWriter.Write(destStream, size.Width, size.Height,
|
||||||
srcImage.Select( im => im.Image ));
|
srcImage.Select(im => im.Image));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ExtractFiles(string[] args)
|
public static void ExtractFiles(string[] args)
|
||||||
@@ -380,14 +381,18 @@ namespace OpenRA.Utility
|
|||||||
var manifest = new Manifest(mods);
|
var manifest = new Manifest(mods);
|
||||||
FileSystem.LoadFromManifest(manifest);
|
FileSystem.LoadFromManifest(manifest);
|
||||||
|
|
||||||
foreach( var f in files )
|
foreach (var f in files)
|
||||||
{
|
{
|
||||||
|
if (f == "--userdir")
|
||||||
|
break;
|
||||||
|
|
||||||
var src = FileSystem.Open(f);
|
var src = FileSystem.Open(f);
|
||||||
if (src == null)
|
if (src == null)
|
||||||
throw new InvalidOperationException("File not found: {0}".F(f));
|
throw new InvalidOperationException("File not found: {0}".F(f));
|
||||||
var data = src.ReadAllBytes();
|
var data = src.ReadAllBytes();
|
||||||
|
var output = args.Contains("--userdir") ? Platform.SupportDir+f : f;
|
||||||
File.WriteAllBytes( f, data );
|
File.WriteAllBytes(output, data);
|
||||||
|
Console.WriteLine(output+" saved.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace OpenRA.Utility
|
|||||||
Console.WriteLine(" --shp PNGFILE FRAMEWIDTH Convert a single PNG with multiple frames appended after another to a SHP");
|
Console.WriteLine(" --shp PNGFILE FRAMEWIDTH Convert a single PNG with multiple frames appended after another to a SHP");
|
||||||
Console.WriteLine(" --png SHPFILE PALETTE [--noshadow] Convert a SHP to a PNG containing all of its frames, optionally removing the shadow");
|
Console.WriteLine(" --png SHPFILE PALETTE [--noshadow] Convert a SHP to a PNG containing all of its frames, optionally removing the shadow");
|
||||||
Console.WriteLine(" --fromd2 DUNE2SHP C&CSHP Convert a Dune II SHP (C&C mouse cursor) to C&C SHP format.");
|
Console.WriteLine(" --fromd2 DUNE2SHP C&CSHP Convert a Dune II SHP (C&C mouse cursor) to C&C SHP format.");
|
||||||
Console.WriteLine(" --extract MOD[,MOD]* FILES Extract files from mod packages");
|
Console.WriteLine(" --extract MOD[,MOD]* FILES [--userdir] Extract files from mod packages to the current (or user) directory");
|
||||||
Console.WriteLine(" --tmp-png MOD[,MOD]* THEATER FILES Extract terrain tiles to PNG");
|
Console.WriteLine(" --tmp-png MOD[,MOD]* THEATER FILES Extract terrain tiles to PNG");
|
||||||
Console.WriteLine(" --remap SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP Remap SHPs to another palette");
|
Console.WriteLine(" --remap SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP Remap SHPs to another palette");
|
||||||
Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--noshadow] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally removing the shadow.");
|
Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--noshadow] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally removing the shadow.");
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ Packages:
|
|||||||
~scores2.mix
|
~scores2.mix
|
||||||
~transit.mix
|
~transit.mix
|
||||||
|
|
||||||
|
PackageContents:
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
mods/cnc/rules/defaults.yaml
|
mods/cnc/rules/defaults.yaml
|
||||||
mods/cnc/rules/system.yaml
|
mods/cnc/rules/system.yaml
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Background@MAINMENU:
|
|||||||
X:(WINDOW_RIGHT - WIDTH)/2
|
X:(WINDOW_RIGHT - WIDTH)/2
|
||||||
Y:(WINDOW_BOTTOM - HEIGHT)/2
|
Y:(WINDOW_BOTTOM - HEIGHT)/2
|
||||||
Width:250
|
Width:250
|
||||||
Height:420
|
Height:460
|
||||||
Visible:true
|
Visible:true
|
||||||
Logic:MainMenuButtonsLogic
|
Logic:MainMenuButtonsLogic
|
||||||
Children:
|
Children:
|
||||||
@@ -63,11 +63,18 @@ Background@MAINMENU:
|
|||||||
Height:25
|
Height:25
|
||||||
Text:Replay Viewer
|
Text:Replay Viewer
|
||||||
Font:Bold
|
Font:Bold
|
||||||
Button@MAINMENU_BUTTON_QUIT:
|
Button@MAINMENU_BUTTON_ASSET_BROWSER:
|
||||||
X:45
|
X:45
|
||||||
Y:350
|
Y:350
|
||||||
Width:160
|
Width:160
|
||||||
Height:25
|
Height:25
|
||||||
|
Text:Asset Browser
|
||||||
|
Font:Bold
|
||||||
|
Button@MAINMENU_BUTTON_QUIT:
|
||||||
|
X:45
|
||||||
|
Y:390
|
||||||
|
Width:160
|
||||||
|
Height:25
|
||||||
Text:Quit
|
Text:Quit
|
||||||
Font:Bold
|
Font:Bold
|
||||||
Background@PERF_BG:
|
Background@PERF_BG:
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ Packages:
|
|||||||
~main.mix
|
~main.mix
|
||||||
conquer.mix
|
conquer.mix
|
||||||
|
|
||||||
|
PackageContents:
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
mods/d2k/rules/system.yaml
|
mods/d2k/rules/system.yaml
|
||||||
mods/d2k/rules/defaults.yaml
|
mods/d2k/rules/defaults.yaml
|
||||||
@@ -66,6 +68,9 @@ ChromeLayout:
|
|||||||
mods/ra/chrome/cheats.yaml
|
mods/ra/chrome/cheats.yaml
|
||||||
mods/ra/chrome/musicplayer.yaml
|
mods/ra/chrome/musicplayer.yaml
|
||||||
mods/d2k/chrome/tooltips.yaml
|
mods/d2k/chrome/tooltips.yaml
|
||||||
|
mods/ra/chrome/assetbrowser.yaml
|
||||||
|
mods/ra/chrome/convertassets.yaml
|
||||||
|
|
||||||
Weapons:
|
Weapons:
|
||||||
mods/d2k/weapons/defaults.yaml
|
mods/d2k/weapons/defaults.yaml
|
||||||
mods/d2k/weapons/explosions.yaml
|
mods/d2k/weapons/explosions.yaml
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
203
mods/ra/chrome/assetbrowser.yaml
Normal file
203
mods/ra/chrome/assetbrowser.yaml
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
Background@ASSETBROWSER_BG:
|
||||||
|
Logic:AssetBrowserLogic
|
||||||
|
X:(WINDOW_RIGHT - WIDTH)/2
|
||||||
|
Y:(WINDOW_BOTTOM - HEIGHT)/2
|
||||||
|
Width:700
|
||||||
|
Height:410
|
||||||
|
Children:
|
||||||
|
Label@ASSETBROWSER_TITLE:
|
||||||
|
X:0
|
||||||
|
Y:20
|
||||||
|
Width:PARENT_RIGHT
|
||||||
|
Height:25
|
||||||
|
Text:Game Asset Viewer & Converter
|
||||||
|
Align:Center
|
||||||
|
Font:Bold
|
||||||
|
DropDownButton@SOURCE_SELECTOR:
|
||||||
|
X:40
|
||||||
|
Y:45
|
||||||
|
Width:160
|
||||||
|
Height:25
|
||||||
|
Font:Bold
|
||||||
|
Text:Folders
|
||||||
|
ScrollPanel@ASSET_LIST:
|
||||||
|
X:40
|
||||||
|
Y:80
|
||||||
|
Width:160
|
||||||
|
Height:190
|
||||||
|
Children:
|
||||||
|
ScrollItem@ASSET_TEMPLATE:
|
||||||
|
Width:PARENT_RIGHT-27
|
||||||
|
Height:25
|
||||||
|
X:2
|
||||||
|
Y:0
|
||||||
|
Visible:false
|
||||||
|
Children:
|
||||||
|
Label@TITLE:
|
||||||
|
X:10
|
||||||
|
Width:PARENT_RIGHT-20
|
||||||
|
Height:25
|
||||||
|
TextField@FILENAME_INPUT:
|
||||||
|
X:40
|
||||||
|
Y:280
|
||||||
|
Width:140
|
||||||
|
Height:25
|
||||||
|
Button@LOAD_BUTTON:
|
||||||
|
X:40
|
||||||
|
Y:310
|
||||||
|
Width:140
|
||||||
|
Height:25
|
||||||
|
Text:Load
|
||||||
|
Font:Bold
|
||||||
|
Key:return
|
||||||
|
Label@PREVIEW_TITLE:
|
||||||
|
X:320
|
||||||
|
Y:45
|
||||||
|
Width:PARENT_RIGHT
|
||||||
|
Height:25
|
||||||
|
Text:Preview
|
||||||
|
Font:Bold
|
||||||
|
Background@SPRITE_BG:
|
||||||
|
X:220
|
||||||
|
Y:80
|
||||||
|
Width:250
|
||||||
|
Height:250
|
||||||
|
Background:dialog4
|
||||||
|
Children:
|
||||||
|
ShpImage@SPRITE:
|
||||||
|
X:4
|
||||||
|
Y:4
|
||||||
|
Width:246
|
||||||
|
Height:246
|
||||||
|
Image:mouse
|
||||||
|
Palette:colorpicker
|
||||||
|
Label@ACTIONS_TITLE:
|
||||||
|
X:PARENT_RIGHT - 150
|
||||||
|
Y:45
|
||||||
|
Width:PARENT_RIGHT
|
||||||
|
Height:25
|
||||||
|
Text:Actions
|
||||||
|
Font:Bold
|
||||||
|
Button@EXPORT_BUTTON:
|
||||||
|
X:PARENT_RIGHT - 200
|
||||||
|
Y:80
|
||||||
|
Width:160
|
||||||
|
Height:25
|
||||||
|
Text:Selected to PNG
|
||||||
|
Font:Bold
|
||||||
|
Button@EXTRACT_BUTTON:
|
||||||
|
X:PARENT_RIGHT - 200
|
||||||
|
Y:115
|
||||||
|
Width:160
|
||||||
|
Height:25
|
||||||
|
Text:Extract all to PNG
|
||||||
|
Font:Bold
|
||||||
|
TextField@IMAGE_FILENAME_INPUT:
|
||||||
|
X:PARENT_RIGHT - 200
|
||||||
|
Y:PARENT_BOTTOM - 235
|
||||||
|
Width:100
|
||||||
|
Height:25
|
||||||
|
Text:pixelart.png
|
||||||
|
TextField@IMAGE_SIZE_INPUT:
|
||||||
|
X:PARENT_RIGHT - 90
|
||||||
|
Y:PARENT_BOTTOM - 235
|
||||||
|
Width:50
|
||||||
|
Height:25
|
||||||
|
Text:width
|
||||||
|
Button@IMPORT_BUTTON:
|
||||||
|
X:PARENT_RIGHT - 200
|
||||||
|
Y:PARENT_BOTTOM - 200
|
||||||
|
Width:160
|
||||||
|
Height:25
|
||||||
|
Text:Import from PNG
|
||||||
|
Font:Bold
|
||||||
|
Button@CLOSE_BUTTON:
|
||||||
|
X:PARENT_RIGHT - 200
|
||||||
|
Y:PARENT_BOTTOM - 115
|
||||||
|
Width:160
|
||||||
|
Height:25
|
||||||
|
Text:Close
|
||||||
|
Font:Bold
|
||||||
|
Key:escape
|
||||||
|
Container@FRAME_SELECTOR:
|
||||||
|
X:45
|
||||||
|
Y:360
|
||||||
|
Children:
|
||||||
|
Button@BUTTON_PREV:
|
||||||
|
X:0
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
Children:
|
||||||
|
Image@IMAGE_PREV:
|
||||||
|
X:0
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
ImageCollection:music
|
||||||
|
ImageName:prev
|
||||||
|
Button@BUTTON_PLAY:
|
||||||
|
X:35
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
Children:
|
||||||
|
Image@IMAGE_PLAY:
|
||||||
|
X:0
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
ImageCollection:music
|
||||||
|
ImageName:play
|
||||||
|
Button@BUTTON_PAUSE:
|
||||||
|
Visible: no
|
||||||
|
X:35
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
Children:
|
||||||
|
Image@IMAGE_PAUSE:
|
||||||
|
X:0
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
ImageCollection:music
|
||||||
|
ImageName:pause
|
||||||
|
Button@BUTTON_STOP:
|
||||||
|
X:70
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
Children:
|
||||||
|
Image@IMAGE_STOP:
|
||||||
|
X:0
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
ImageCollection:music
|
||||||
|
ImageName:stop
|
||||||
|
Button@BUTTON_NEXT:
|
||||||
|
X:105
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
Children:
|
||||||
|
Image@IMAGE_NEXT:
|
||||||
|
X:0
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
ImageCollection:music
|
||||||
|
ImageName:next
|
||||||
|
Slider@FRAME_SLIDER:
|
||||||
|
X:160
|
||||||
|
Y:0
|
||||||
|
Width:410
|
||||||
|
Height:20
|
||||||
|
MinimumValue: 0
|
||||||
|
Label@FRAME_COUNT:
|
||||||
|
X:585
|
||||||
|
Y:0
|
||||||
|
Width:25
|
||||||
|
Height:25
|
||||||
|
Font:Bold
|
||||||
47
mods/ra/chrome/convertassets.yaml
Normal file
47
mods/ra/chrome/convertassets.yaml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
Background@CONVERT_ASSETS_PANEL:
|
||||||
|
Logic:ConvertGameFilesLogic
|
||||||
|
X:(WINDOW_RIGHT - WIDTH)/2
|
||||||
|
Y:(WINDOW_BOTTOM - HEIGHT)/2
|
||||||
|
Width:500
|
||||||
|
Height:160
|
||||||
|
Children:
|
||||||
|
Label@TITLE:
|
||||||
|
X:0
|
||||||
|
Y:20
|
||||||
|
Width:PARENT_RIGHT
|
||||||
|
Height:25
|
||||||
|
Text:Extracting and Converting Gamefiles
|
||||||
|
Align:Center
|
||||||
|
Font:Bold
|
||||||
|
Container@EXTRACTING:
|
||||||
|
Width:PARENT_RIGHT
|
||||||
|
Height:PARENT_BOTTOM
|
||||||
|
Visible: false
|
||||||
|
Children:
|
||||||
|
ProgressBar@PROGRESS_BAR:
|
||||||
|
X:50
|
||||||
|
Y:55
|
||||||
|
Width:PARENT_RIGHT - 100
|
||||||
|
Height:25
|
||||||
|
Label@STATUS_LABEL:
|
||||||
|
X:50
|
||||||
|
Y:80
|
||||||
|
Width:PARENT_RIGHT - 100
|
||||||
|
Height:25
|
||||||
|
Align:Left
|
||||||
|
Button@RETRY_BUTTON:
|
||||||
|
X:PARENT_RIGHT - 280
|
||||||
|
Y:PARENT_BOTTOM - 45
|
||||||
|
Width:120
|
||||||
|
Height:25
|
||||||
|
Text:Retry
|
||||||
|
Font:Bold
|
||||||
|
Key:return
|
||||||
|
Button@BACK_BUTTON:
|
||||||
|
X:PARENT_RIGHT - 140
|
||||||
|
Y:PARENT_BOTTOM - 45
|
||||||
|
Width:120
|
||||||
|
Height:25
|
||||||
|
Text:Back
|
||||||
|
Font:Bold
|
||||||
|
Key:escape
|
||||||
@@ -23,7 +23,7 @@ Container@MAINMENU:
|
|||||||
X:(WINDOW_RIGHT - WIDTH)/8
|
X:(WINDOW_RIGHT - WIDTH)/8
|
||||||
Y:(WINDOW_BOTTOM - HEIGHT)/2
|
Y:(WINDOW_BOTTOM - HEIGHT)/2
|
||||||
Width:250
|
Width:250
|
||||||
Height:505
|
Height:555
|
||||||
Logic:MainMenuButtonsLogic
|
Logic:MainMenuButtonsLogic
|
||||||
Children:
|
Children:
|
||||||
Label@MAINMENU_LABEL_TITLE:
|
Label@MAINMENU_LABEL_TITLE:
|
||||||
@@ -83,11 +83,18 @@ Container@MAINMENU:
|
|||||||
Height:35
|
Height:35
|
||||||
Text:Replay Viewer
|
Text:Replay Viewer
|
||||||
Font:Bold
|
Font:Bold
|
||||||
Button@MAINMENU_BUTTON_QUIT:
|
Button@MAINMENU_BUTTON_ASSET_BROWSER:
|
||||||
X:45
|
X:45
|
||||||
Y:430
|
Y:430
|
||||||
Width:160
|
Width:160
|
||||||
Height:35
|
Height:35
|
||||||
|
Text:Asset Browser
|
||||||
|
Font:Bold
|
||||||
|
Button@MAINMENU_BUTTON_QUIT:
|
||||||
|
X:45
|
||||||
|
Y:480
|
||||||
|
Width:160
|
||||||
|
Height:35
|
||||||
Text:Quit
|
Text:Quit
|
||||||
Font:Bold
|
Font:Bold
|
||||||
Background@PERF_BG:
|
Background@PERF_BG:
|
||||||
|
|||||||
227
mods/ra/mix/conquer.yaml
Normal file
227
mods/ra/mix/conquer.yaml
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
# conquer.mix filename list for the game asset browser
|
||||||
|
#appear1.aud:
|
||||||
|
#beepy6.aud:
|
||||||
|
#briefing.aud:
|
||||||
|
#clock1.aud:
|
||||||
|
#country1.aud:
|
||||||
|
#country4.aud:
|
||||||
|
#keystrok.aud:
|
||||||
|
#mapwipe2.aud:
|
||||||
|
#mapwipe5.aud:
|
||||||
|
#scold1.aud:
|
||||||
|
#sfx4.aud:
|
||||||
|
#toney10.aud:
|
||||||
|
#toney4.aud:
|
||||||
|
#toney7.aud:
|
||||||
|
#type.fnt:
|
||||||
|
#alibackh.pcx:
|
||||||
|
#sovback.pcx:
|
||||||
|
120mm.shp:
|
||||||
|
1tnk.shp:light tank
|
||||||
|
2tnk.shp:medium tank
|
||||||
|
3tnk.shp:heavy tank
|
||||||
|
4tnk.shp:mammoth tank
|
||||||
|
50cal.shp:
|
||||||
|
afld.shp:
|
||||||
|
afldmake.shp:
|
||||||
|
agun.shp:
|
||||||
|
agunmake.shp:
|
||||||
|
apc.shp:
|
||||||
|
apwr.shp:
|
||||||
|
apwrmake.shp:
|
||||||
|
armor.shp:
|
||||||
|
art-exp1.shp:
|
||||||
|
arty.shp:
|
||||||
|
atek.shp:
|
||||||
|
atekmake.shp:
|
||||||
|
atomicdn.shp:
|
||||||
|
atomicup.shp:
|
||||||
|
atomsfx.shp:
|
||||||
|
badr.shp:
|
||||||
|
bar3bhr.shp:
|
||||||
|
bar3blu.shp:
|
||||||
|
bar3red.shp:
|
||||||
|
bar3rhr.shp:
|
||||||
|
barb.shp:
|
||||||
|
barl.shp:
|
||||||
|
barr.shp:
|
||||||
|
barrmake.shp:
|
||||||
|
bio.shp:
|
||||||
|
biomake.shp:
|
||||||
|
bomb.shp:
|
||||||
|
bomblet.shp:
|
||||||
|
brik.shp:
|
||||||
|
brl3.shp:
|
||||||
|
burn-l.shp:
|
||||||
|
burn-m.shp:
|
||||||
|
burn-s.shp:
|
||||||
|
ca.shp:
|
||||||
|
chronbox.shp:
|
||||||
|
countrya.shp:
|
||||||
|
countrye.shp:
|
||||||
|
credsa.shp:
|
||||||
|
credsahr.shp:
|
||||||
|
credsu.shp:
|
||||||
|
credsuhr.shp:
|
||||||
|
cycl.shp:
|
||||||
|
dd.shp:
|
||||||
|
deviator.shp:
|
||||||
|
dog.shp:
|
||||||
|
dogbullt.shp:
|
||||||
|
dollar.shp:
|
||||||
|
dome.shp:
|
||||||
|
domemake.shp:
|
||||||
|
dragon.shp:
|
||||||
|
earth.shp:
|
||||||
|
ebtn-dn.shp:
|
||||||
|
electdog.shp:
|
||||||
|
empulse.shp:
|
||||||
|
fact.shp:
|
||||||
|
factmake.shp:
|
||||||
|
fb1.shp:
|
||||||
|
fb2.shp:
|
||||||
|
fball1.shp:
|
||||||
|
fcom.shp:
|
||||||
|
fenc.shp:
|
||||||
|
fire1.shp:
|
||||||
|
fire2.shp:
|
||||||
|
fire3.shp:
|
||||||
|
fire4.shp:
|
||||||
|
fix.shp:
|
||||||
|
fixmake.shp:
|
||||||
|
flagfly.shp:
|
||||||
|
flak.shp:
|
||||||
|
flmspt.shp:
|
||||||
|
fpls.shp:
|
||||||
|
fpower.shp:
|
||||||
|
frag1.shp:
|
||||||
|
ftnk.shp:
|
||||||
|
ftur.shp:
|
||||||
|
fturmake.shp:
|
||||||
|
gap.shp:
|
||||||
|
gapmake.shp:
|
||||||
|
gpsbox.shp:
|
||||||
|
gun.shp:
|
||||||
|
gunfire.shp:
|
||||||
|
gunmake.shp:
|
||||||
|
h2o_exp1.shp:
|
||||||
|
h2o_exp2.shp:
|
||||||
|
h2o_exp3.shp:
|
||||||
|
harv.shp:
|
||||||
|
heli.shp:
|
||||||
|
hind.shp:
|
||||||
|
hisc1-hr.shp:
|
||||||
|
hisc2-hr.shp:
|
||||||
|
hiscore1.shp:
|
||||||
|
hiscore2.shp:
|
||||||
|
hosp.shp:
|
||||||
|
hospmake.shp:
|
||||||
|
hpad.shp:
|
||||||
|
hpadmake.shp:
|
||||||
|
invulbox.shp:
|
||||||
|
invun.shp:
|
||||||
|
iron.shp:
|
||||||
|
ironmake.shp:
|
||||||
|
jeep.shp:
|
||||||
|
kenn.shp:
|
||||||
|
kennmake.shp:
|
||||||
|
litning.shp:
|
||||||
|
lrotor.shp:
|
||||||
|
lst.shp:
|
||||||
|
mcv.shp:
|
||||||
|
mgg.shp:
|
||||||
|
mgun.shp:
|
||||||
|
mhq.shp:
|
||||||
|
mig.shp:
|
||||||
|
mine.shp:
|
||||||
|
minigun.shp:
|
||||||
|
minp.shp:
|
||||||
|
minpmake.shp:
|
||||||
|
minv.shp:
|
||||||
|
minvmake.shp:
|
||||||
|
miss.shp:
|
||||||
|
missile.shp:
|
||||||
|
missile2.shp:
|
||||||
|
mlrs.shp:
|
||||||
|
mnly.shp:
|
||||||
|
mrj.shp:
|
||||||
|
napalm1.shp:
|
||||||
|
napalm2.shp:
|
||||||
|
napalm3.shp:
|
||||||
|
orca.shp:
|
||||||
|
parabomb.shp:
|
||||||
|
parabox.shp:
|
||||||
|
parach.shp:
|
||||||
|
patriot.shp:
|
||||||
|
pbox.shp:
|
||||||
|
pboxmake.shp:
|
||||||
|
pdox.shp:
|
||||||
|
pdoxmake.shp:
|
||||||
|
piff.shp:
|
||||||
|
piffpiff.shp:
|
||||||
|
powr.shp:
|
||||||
|
powrmake.shp:
|
||||||
|
pt.shp:
|
||||||
|
pumpmake.shp:
|
||||||
|
radarfrm.shp:
|
||||||
|
rapid.shp:
|
||||||
|
rrotor.shp:
|
||||||
|
sam.shp:
|
||||||
|
samfire.shp:
|
||||||
|
sammake.shp:
|
||||||
|
sbag.shp:
|
||||||
|
scrate.shp:
|
||||||
|
select.shp:
|
||||||
|
repair.shp:
|
||||||
|
shadow.shp:
|
||||||
|
silo.shp:
|
||||||
|
silomake.shp:
|
||||||
|
smig.shp:
|
||||||
|
smoke_m.shp:
|
||||||
|
smokey.shp:
|
||||||
|
smokland.shp:
|
||||||
|
sonarbox.shp:
|
||||||
|
speed.shp:
|
||||||
|
spen.shp:
|
||||||
|
spenmake.shp:
|
||||||
|
sputdoor.shp:
|
||||||
|
sputnik.shp:
|
||||||
|
ss.shp:
|
||||||
|
ssam.shp:
|
||||||
|
stealth2.shp:
|
||||||
|
stek.shp:
|
||||||
|
stekmake.shp:
|
||||||
|
stnk.shp:
|
||||||
|
syrd.shp:
|
||||||
|
syrdmake.shp:
|
||||||
|
tent.shp:
|
||||||
|
tentmake.shp:
|
||||||
|
time.shp:
|
||||||
|
timehr.shp:
|
||||||
|
tquake.shp:
|
||||||
|
tran.shp:
|
||||||
|
truk.shp:
|
||||||
|
tsla.shp:
|
||||||
|
tslamake.shp:
|
||||||
|
turr.shp:
|
||||||
|
twinkle1.shp:
|
||||||
|
twinkle2.shp:
|
||||||
|
twinkle3.shp:
|
||||||
|
u2.shp:
|
||||||
|
v19.shp:
|
||||||
|
v2.shp:
|
||||||
|
v2rl.shp:
|
||||||
|
veh-hit1.shp:
|
||||||
|
veh-hit2.shp:
|
||||||
|
wake.shp:
|
||||||
|
wcrate.shp:
|
||||||
|
weap.shp:
|
||||||
|
weap2.shp:
|
||||||
|
weapmake.shp:
|
||||||
|
wood.shp:
|
||||||
|
wwcrate.shp:
|
||||||
|
yak.shp:
|
||||||
|
#trans.icn:
|
||||||
|
#ali-tran.wsa:
|
||||||
|
#mltiplyr.wsa:
|
||||||
|
#sov-tran.wsa:
|
||||||
135
mods/ra/mix/hires.yaml
Normal file
135
mods/ra/mix/hires.yaml
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# hires.mix filename list for the game asset browser
|
||||||
|
1tnkicon.shp:
|
||||||
|
2tnkicon.shp:
|
||||||
|
3tnkicon.shp:
|
||||||
|
4tnkicon.shp:
|
||||||
|
afldicon.shp:
|
||||||
|
agunicon.shp:
|
||||||
|
apcicon.shp:
|
||||||
|
apwricon.shp:
|
||||||
|
artyicon.shp:
|
||||||
|
atekicon.shp:
|
||||||
|
atomicon.shp:
|
||||||
|
badricon.shp:
|
||||||
|
barricon.shp:
|
||||||
|
brikicon.shp:
|
||||||
|
btn-dn.shp:
|
||||||
|
btn-pl.shp:
|
||||||
|
btn-st.shp:
|
||||||
|
btn-up.shp:
|
||||||
|
c1.shp:
|
||||||
|
c2.shp:
|
||||||
|
caicon.shp:
|
||||||
|
camicon.shp:
|
||||||
|
chan.shp:
|
||||||
|
clock.shp:
|
||||||
|
dd-bkgnd.shp:
|
||||||
|
dd-botm.shp:
|
||||||
|
dd-crnr.shp:
|
||||||
|
dd-edge.shp:
|
||||||
|
dd-left.shp:
|
||||||
|
dd-right.shp:
|
||||||
|
dd-top.shp:
|
||||||
|
ddicon.shp:
|
||||||
|
delphi.shp:
|
||||||
|
dogicon.shp:
|
||||||
|
domeicon.shp:
|
||||||
|
domficon.shp:
|
||||||
|
e1.shp:
|
||||||
|
e1icon.shp:
|
||||||
|
e2.shp:
|
||||||
|
e2icon.shp:
|
||||||
|
e3.shp:
|
||||||
|
e3icon.shp:
|
||||||
|
e4.shp:
|
||||||
|
e4icon.shp:
|
||||||
|
e5.shp:
|
||||||
|
e6.shp:
|
||||||
|
e6icon.shp:
|
||||||
|
e7.shp:
|
||||||
|
e7icon.shp:
|
||||||
|
einstein.shp:
|
||||||
|
facficon.shp:
|
||||||
|
facticon.shp:
|
||||||
|
fencicon.shp:
|
||||||
|
fixicon.shp:
|
||||||
|
fturicon.shp:
|
||||||
|
gapicon.shp:
|
||||||
|
gnrl.shp:
|
||||||
|
gpssicon.shp:
|
||||||
|
gunicon.shp:
|
||||||
|
harvicon.shp:
|
||||||
|
hboxicon.shp:
|
||||||
|
heliicon.shp:
|
||||||
|
hindicon.shp:
|
||||||
|
hpadicon.shp:
|
||||||
|
infxicon.shp:
|
||||||
|
ironicon.shp:
|
||||||
|
jeepicon.shp:
|
||||||
|
kennicon.shp:
|
||||||
|
lsticon.shp:
|
||||||
|
map.shp:
|
||||||
|
mcvicon.shp:
|
||||||
|
medi.shp:
|
||||||
|
mediicon.shp:
|
||||||
|
mggicon.shp:
|
||||||
|
migicon.shp:
|
||||||
|
mnlyicon.shp:
|
||||||
|
mrjicon.shp:
|
||||||
|
msloicon.shp:
|
||||||
|
natoradr.shp:
|
||||||
|
nradrfrm.shp:
|
||||||
|
pbmbicon.shp:
|
||||||
|
pboxicon.shp:
|
||||||
|
pdoxicon.shp:
|
||||||
|
pinficon.shp:
|
||||||
|
pips.shp:
|
||||||
|
power.shp:
|
||||||
|
powerbar.shp:
|
||||||
|
powricon.shp:
|
||||||
|
procicon.shp:
|
||||||
|
pticon.shp:
|
||||||
|
pulse.shp:
|
||||||
|
repair.shp:
|
||||||
|
samicon.shp:
|
||||||
|
sbagicon.shp:
|
||||||
|
sell.shp:
|
||||||
|
side1na.shp:
|
||||||
|
side1us.shp:
|
||||||
|
side2na.shp:
|
||||||
|
side2us.shp:
|
||||||
|
side3na.shp:
|
||||||
|
side3us.shp:
|
||||||
|
#sidebar.shp:will crash
|
||||||
|
siloicon.shp:
|
||||||
|
smigicon.shp:
|
||||||
|
sonricon.shp:
|
||||||
|
speficon.shp:
|
||||||
|
spenicon.shp:
|
||||||
|
spy.shp:
|
||||||
|
spyicon.shp:
|
||||||
|
ssicon.shp:
|
||||||
|
stekicon.shp:
|
||||||
|
strip.shp:
|
||||||
|
stripdn.shp:
|
||||||
|
stripna.shp:
|
||||||
|
stripup.shp:
|
||||||
|
stripus.shp:
|
||||||
|
syrdicon.shp:
|
||||||
|
syrficon.shp:
|
||||||
|
tabs.shp:
|
||||||
|
tenticon.shp:
|
||||||
|
thf.shp:
|
||||||
|
thficon.shp:
|
||||||
|
tranicon.shp:
|
||||||
|
trukicon.shp:
|
||||||
|
tslaicon.shp:
|
||||||
|
u2icon.shp:
|
||||||
|
uradrfrm.shp:
|
||||||
|
ussrradr.shp:
|
||||||
|
v2rlicon.shp:
|
||||||
|
warpicon.shp:
|
||||||
|
weaficon.shp:
|
||||||
|
weapicon.shp:
|
||||||
|
yakicon.shp:
|
||||||
|
#mouse.shp:Dune II format
|
||||||
@@ -29,6 +29,10 @@ Packages:
|
|||||||
~movies1.mix
|
~movies1.mix
|
||||||
~movies2.mix
|
~movies2.mix
|
||||||
|
|
||||||
|
PackageContents:
|
||||||
|
mods/ra/mix/conquer.yaml
|
||||||
|
mods/ra/mix/hires.yaml
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
mods/ra/rules/defaults.yaml
|
mods/ra/rules/defaults.yaml
|
||||||
mods/ra/rules/system.yaml
|
mods/ra/rules/system.yaml
|
||||||
@@ -73,6 +77,8 @@ ChromeLayout:
|
|||||||
mods/ra/chrome/cheats.yaml
|
mods/ra/chrome/cheats.yaml
|
||||||
mods/ra/chrome/musicplayer.yaml
|
mods/ra/chrome/musicplayer.yaml
|
||||||
mods/ra/chrome/tooltips.yaml
|
mods/ra/chrome/tooltips.yaml
|
||||||
|
mods/ra/chrome/assetbrowser.yaml
|
||||||
|
mods/ra/chrome/convertassets.yaml
|
||||||
|
|
||||||
Weapons:
|
Weapons:
|
||||||
mods/ra/weapons.yaml
|
mods/ra/weapons.yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user