diff options
Diffstat (limited to 'GfxEdInterface.cs')
-rw-r--r-- | GfxEdInterface.cs | 593 |
1 files changed, 593 insertions, 0 deletions
diff --git a/GfxEdInterface.cs b/GfxEdInterface.cs new file mode 100644 index 0000000..2491a08 --- /dev/null +++ b/GfxEdInterface.cs @@ -0,0 +1,593 @@ +// GfxEd interface +// Copyright (C) 2004 Ian Cowburn +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// $Id$ +// +using System; +using System.Collections; +using System.Drawing; +using System.Windows.Forms; +using System.IO; + +namespace GfxEdInterface +{ + /// <summary> + /// Defines the interface a plugin must follow + /// </summary> + public interface IPlugin + { + /// <summary> + /// The description for this plugin + /// </summary> + string Description {get;} + + /// <summary> + /// The short name (for drop down list use) of this plugin + /// </summary> + string ShortName {get;} + + /// <summary> + /// The copyright and author information for this plugin + /// </summary> + string Author {get;} + + /// <summary> + /// The URL where this plugin can be found + /// </summary> + string URL {get;} + + /// <summary> + /// The maximum number of colours for a sprite + /// </summary> + uint MaxColours {get;} + + /// <summary> + /// The machines palette. Sprite colours are selected from this. + /// </summary> + /// <remarks> + /// Note that colour zero is considered the transparent/background + /// colour and cannot be selected for drawing. On platforms where the + /// actual colour could be used, duplicate it and weight your palette + /// routines when outputing accordingly. + /// </remarks> + Colour[] Palette {get;} + + /// <summary> + /// An array indicating that that colour in the sprite can be changed. + /// </summary> + bool[] SprPalEditable {get;} + + /// <summary> + /// An array indicating that that colour in the sprite is common to all. + /// </summary> + bool[] SprPalCommon {get;} + + /// <summary> + /// The allowable sprite sizes. + /// </summary> + SpriteSize[] AllowedSizes {get;} + + /// <summary> + /// The default extension for exports + /// </summary> + string ExportExtension {get;} + + /// <summary> + /// Exports the sprites. + /// </summary> + /// <param name="path">The exported filename</param> + /// <param name="sprites">A list of sprites to export</param> + /// <returns></returns> + bool Export(string path, SpriteList sprites); + + /// <summary> + /// Get the configuration object for the plugin. + /// </summary> + /// <remarks> + /// If there is no configuration required for the plugin, null can be + /// returned. + /// </remarks> + IConfig Config {get;} + + /// <summary> + /// Get the processing object for the plugin. + /// </summary> + /// <remarks> + /// If there is no processing supplied by the plugin, null can be + /// returned. + /// </remarks> + IProcess Process {get;} + } + + + /// <summary> + /// Defines the configuration interface for a plugin. + /// </summary> + public interface IConfig + { + /// <summary> + /// Shows the configuration dialog. + /// </summary> + void Settings(Form parent); + + /// <summary> + /// Outputs the configuration to the suppluied stream. + /// </summary> + /// <remarks> + /// All file operations are done using text files. + /// </remarks> + /// <param name="stream">The output stream</param> + void Output(TextWriter stream); + + /// <summary> + /// Inputs the configuration from the suppluied stream. + /// </summary> + /// <remarks> + /// All file operations are done using text files. + /// </remarks> + /// <param name="stream">The output stream</param> + void Input(TextReader stream); + } + + + /// <summary> + /// Defines the processing interface for a plugin. + /// </summary> + public interface IProcess + { + /// <summary> + /// Process the sprite. + /// </summary> + void Single(Sprite s); + + /// <summary> + /// Process all the sprites. + /// </summary> + void All(SpriteList s); + } + + + /// <summary> + /// Defines the allowable sizes for a sprite and their aspect ratios + /// </summary> + public class SpriteSize + { + public SpriteSize(uint w, uint h, uint xaspect, uint yaspect) + { + m_width=w; + m_height=h; + m_xaspect=xaspect; + m_yaspect=yaspect; + } + + public uint Width {get {return m_width;}} + public uint Height {get {return m_height;}} + public uint XAspect {get {return m_xaspect;}} + public uint YAspect {get {return m_yaspect;}} + + public override string ToString() + { + return m_width.ToString()+","+m_height.ToString(); + } + + private uint m_width; + private uint m_height; + private uint m_xaspect; + private uint m_yaspect; + } + + + /// <summary> + /// Describes a colour. And yes, a *very* dumb class name. + /// </summary> + public class Colour + { + public Colour(string name, byte red, byte green, byte blue) + { + m_name=name; + m_red=red; + m_blue=blue; + m_green=green; + } + + public override string ToString() + { + return Name; + } + + public string Name + { + get {return m_name;} + set {m_name=value;} + } + + public byte Red + { + get {return m_red;} + set {m_red=value;} + } + + public byte Green + { + get {return m_green;} + set {m_green=value;} + } + + public byte Blue + { + get {return m_blue;} + set {m_blue=value;} + } + + public Color DrawCol + { + get {return Color.FromArgb(m_red,m_green,m_blue);} + } + + private string m_name; + private byte m_red; + private byte m_green; + private byte m_blue; + } + + + /// <summary> + /// Describes a sprite + /// </summary> + public class Sprite + { + public Sprite(string name, uint width, uint height, uint maxcol) + { + m_name=name; + m_width=width; + m_height=height; + m_data=new uint[m_width,m_height]; + m_pal=new uint[maxcol]; + + for(uint f=0;f<maxcol;f++) + { + m_pal[f]=f; + } + } + + public Sprite(string name, SpriteSize size, uint maxcol) + { + m_name=name; + m_width=size.Width; + m_height=size.Height; + m_data=new uint[m_width,m_height]; + m_pal=new uint[maxcol]; + + for(uint f=0;f<maxcol;f++) + { + m_pal[f]=f; + } + } + + public Sprite(Sprite old) + { + m_name=old.m_name; + m_width=old.m_width; + m_height=old.m_height; + m_data=new uint[m_width,m_height]; + m_pal=new uint[old.m_pal.Length]; + + for(int x=0;x<m_width;x++) + for(int y=0;y<m_height;y++) + m_data[x,y]=old.m_data[x,y]; + + for(int f=0;f<m_pal.Length;f++) + m_pal[f]=old.m_pal[f]; + } + + public string Name + { + get {return m_name;} + set {m_name=value;} + } + + public uint Width + { + get {return m_width;} + } + + public uint Height + { + get {return m_height;} + } + + public void Resize(uint width, uint height) + { + uint[,] data=new uint[width,height]; + uint mx=Math.Min(width,m_width); + uint my=Math.Min(height,m_height); + + for(int x=0;x<mx;x++) + for(int y=0;y<my;y++) + data[x,y]=m_data[x,y]; + + m_width=width; + m_height=height; + m_data=data; + } + + public uint this [uint x, uint y] + { + set {m_data[x,y]=value;} + get {return m_data[x,y];} + } + + public uint Pal(uint i) + { + return m_pal[i]; + } + + public void Pal(uint i, uint c) + { + m_pal[i]=c; + } + + public void Clear() + { + for(int y=0;y<m_height;y++) + for(int x=0;x<m_width;x++) + m_data[x,y]=0; + } + + public void MirrorHorizontal() + { + uint[,] d=new uint[m_width,m_height]; + + for(int y=0;y<m_height;y++) + for(int x=0;x<m_width;x++) + d[x,y]=m_data[m_width-x-1,y]; + + m_data=d; + } + + public void MirrorVertical() + { + uint[,] d=new uint[m_width,m_height]; + + for(int y=0;y<m_height;y++) + for(int x=0;x<m_width;x++) + d[x,y]=m_data[x,m_height-y-1]; + + m_data=d; + } + + public void Scroll(int dx, int dy) + { + uint[,] d=new uint[m_width,m_height]; + + for(int y=0;y<m_height;y++) + for(int x=0;x<m_width;x++) + d[Mod(x+dx,m_width),Mod(y+dy,m_height)]=m_data[x,y]; + + m_data=d; + } + + public void RotateRight() + { + uint[,] d=new uint[m_width,m_height]; + uint min=Math.Min(m_width,m_height); + + for(int y=0;y<m_height;y++) + for(int x=0;x<m_width;x++) + { + long nx=min-y-1; + long ny=x; + + if (nx>=0 && nx<m_width && ny>=0 && ny<m_height) + { + d[nx,ny]=m_data[x,y]; + } + } + + m_data=d; + } + + public void RotateLeft() + { + uint[,] d=new uint[m_width,m_height]; + uint min=Math.Min(m_width,m_height); + + for(int y=0;y<m_height;y++) + for(int x=0;x<m_width;x++) + { + long nx=y; + long ny=min-x-1; + + if (nx>=0 && nx<m_width && ny>=0 && ny<m_height) + { + d[nx,ny]=m_data[x,y]; + } + } + + m_data=d; + } + + public void Output(TextWriter stream) + { + stream.WriteLine(m_name); + stream.WriteLine(m_width); + stream.WriteLine(m_height); + + stream.Write(m_pal.Length); + + for(int f=0;f<m_pal.Length;f++) + { + stream.Write(","+m_pal[f]); + } + + stream.WriteLine(); + + for(int y=0;y<m_height;y++) + { + for(int x=0;x<m_width;x++) + { + if (x==0) + { + stream.Write(m_data[x,y]); + } + else + { + stream.Write(","+m_data[x,y]); + } + } + + stream.WriteLine(); + } + } + + public static Sprite Input(TextReader stream) + { + string name=stream.ReadLine(); + uint width=Convert.ToUInt32(stream.ReadLine()); + uint height=Convert.ToUInt32(stream.ReadLine()); + string[] pal=stream.ReadLine().Split(new Char[1] {','}); + + Sprite s=new Sprite(name, width, height, Convert.ToUInt32(pal[0])); + + for(int f=0;f<s.m_pal.Length;f++) + { + s.m_pal[f]=Convert.ToUInt32(pal[f+1]); + } + + for(uint y=0;y<height;y++) + { + string[] data=stream.ReadLine().Split(new Char[1] {','}); + + for(uint x=0;x<width;x++) + { + s[x,y]=Convert.ToUInt32(data[x]); + } + } + + return s; + } + + // ------------------------------------------------ + // PRIVATE + // + private string m_name; + private uint m_width; + private uint m_height; + private uint[,] m_data; + private uint[] m_pal; + + private int Mod(int v, uint max) + { + while(v<0) + v+=(int)max; + + v=v%(int)max; + + return v; + } + } + + + /// <summary> + /// Describes a list of sprites + /// </summary> + public class SpriteList : IEnumerable + { + public SpriteList() + { + m_list=new ArrayList(); + m_changed=false; + } + + public Sprite this [int i] + { + get {return (Sprite)m_list[i];} + set + { + m_list[i]=value; + m_changed=true; + } + } + + public void Add(Sprite s) + { + m_list.Add(s); + m_changed=true; + } + + public void Insert(int i, Sprite s) + { + m_list.Insert(i,s); + m_changed=true; + } + + public void RemoveAt(int i) + { + m_list.RemoveAt(i); + } + + public int Count + { + get {return m_list.Count;} + } + + public void Clear() + { + m_list.Clear(); + } + + public bool Changed + { + get {return m_changed;} + set {m_changed=value;} + } + + public IEnumerator GetEnumerator() + { + return m_list.GetEnumerator(); + } + + public void Output(TextWriter stream) + { + stream.WriteLine(m_list.Count); + + foreach (Sprite s in m_list) + { + s.Output(stream); + } + } + + public static SpriteList Input(TextReader stream) + { + SpriteList l=new SpriteList(); + int count=Convert.ToInt32(stream.ReadLine()); + + for(int f=0;f<count;f++) + { + l.Add(Sprite.Input(stream)); + } + + return l; + } + + // ------------------------------------------------ + // PRIVATE + // + private ArrayList m_list; + private bool m_changed; + } +} |