diff options
-rw-r--r-- | SpriteEd/AppDelegate.cs | 228 | ||||
-rw-r--r-- | SpriteEd/Main.storyboard | 44 | ||||
-rw-r--r-- | SpriteEd/SpriteSet.cs | 7 | ||||
-rw-r--r-- | SpriteEd/SpriteSetController.cs | 21 | ||||
-rw-r--r-- | SpriteEd/SpriteSetController.designer.cs | 24 |
5 files changed, 247 insertions, 77 deletions
diff --git a/SpriteEd/AppDelegate.cs b/SpriteEd/AppDelegate.cs index 3e51178..9c3aa73 100644 --- a/SpriteEd/AppDelegate.cs +++ b/SpriteEd/AppDelegate.cs @@ -276,28 +276,109 @@ namespace SpriteEd } /// <summary> - /// Convert a mono sprite into a byte. + /// Convert a sprite set into a stream of bytes. /// </summary> - /// <param name="s">The sprite.</param> - /// <param name="x">The starting X co-ord.</param> - /// <param name="y">The Y co-ord.</param> - /// <returns></returns> - private uint SpriteData(Sprite s, uint x, uint y) + /// <param name="write">The action to call with each byte.</param> + /// <param name="set">The sprite set.</param> + /// <param name="export_blank">Export blank sprites.</param> + private void StreamSpriteSet(Action<byte> write, SpriteSet set, bool export_blank) { - uint b = 0; - uint bit = 128; + int bits_per_pixel = 1; + + switch(set.Palette.Size) + { + case 4: + bits_per_pixel = 2; + break; + case 16: + bits_per_pixel = 4; + break; + case 256: + bits_per_pixel = 8; + break; + } - for(uint sx = 0; sx < 8; sx++) + for(uint f = 0; f < 256; f++) { - if (s[x + sx, y] == 1) + Sprite sprite = set[(byte)f]; + + if (export_blank || !IsSpriteBlank(sprite)) { - b |= bit; - } + for(uint y = 0; y < sprite.Height; y++) + { + switch(bits_per_pixel) + { + case 1: + for(uint x = 0; x < sprite.Width; x += 8) + { + uint bit = 128; + uint b = 0; + + for(uint sx = 0; sx < 8; sx++) + { + if ((x + sx) < sprite.Width) + { + if (sprite[x + sx,y] != 0) + { + b |= bit; + } + } + + bit /= 2; + } + + write((byte)b); + } + break; - bit = bit >> 1; - } + case 2: + for(uint x = 0; x < sprite.Width; x += 4) + { + uint b = sprite[x, y] << 6; + + if ((x + 1) < sprite.Width) + { + b |= sprite[x + 1, y] << 4; + } - return b; + if ((x + 2) < sprite.Width) + { + b |= sprite[x + 2, y] << 2; + } + + if ((x + 3) < sprite.Width) + { + b |= sprite[x + 3, y]; + } + + write((byte)b); + } + break; + + case 4: + for(uint x = 0; x < sprite.Width; x += 2) + { + uint b = sprite[x, y] << 4; + + if ((x + 1) < sprite.Width) + { + b |= sprite[x + 1, y]; + } + + write((byte)b); + } + break; + + case 8: + for(uint x = 0; x < sprite.Width; x++) + { + write((byte)sprite[x,y]); + } + break; + } + } + } + } } /// <summary> @@ -307,10 +388,12 @@ namespace SpriteEd [Export("exportBinary:")] private void ExportBinary(NSObject sender) { + if (NSApplication.SharedApplication.KeyWindow == null) + { + return; + } + NSSavePanel fsel = new NSSavePanel(); - ViewController view = ViewController; - bool export_blank = false; - bool export_mono = false; fsel.Title = "Export binary"; fsel.ShowsTagField = false; @@ -319,20 +402,19 @@ namespace SpriteEd { try { - export_blank = view.SpriteSet.Type == SpriteSet.SetType.C64CharacterSet; - export_mono = view.SpriteSet.Palette.Size == 2; + ViewController view = ViewController; + + bool export_blank = view.SpriteSet.Type == SpriteSet.SetType.C64CharacterSet || + view.SpriteSet.Type == SpriteSet.SetType.MonoCharacterSet; FileStream stream = File.Create(fsel.Url.Path); - if (export_mono) - { - for(byte f = 0; f < view.SpriteSet.Size; f++) + StreamSpriteSet + (delegate (byte b) { - if (export_blank || !IsSpriteBlank(view.SpriteSet[f])) - { - } - } - } + stream.WriteByte(b); + }, + view.SpriteSet, export_blank); stream.Close(); } @@ -350,8 +432,12 @@ namespace SpriteEd [Export("exportAssembly:")] private void ExportAssembly(NSObject sender) { + if (NSApplication.SharedApplication.KeyWindow == null) + { + return; + } + NSSavePanel fsel = new NSSavePanel(); - ViewController view = ViewController; fsel.Title = "Export assembly"; fsel.AllowedFileTypes = new string[] {"asm"}; @@ -361,7 +447,38 @@ namespace SpriteEd { try { - FileStream stream = File.Create(fsel.Url.Path); + ViewController view = ViewController; + + bool export_blank = view.SpriteSet.Type == SpriteSet.SetType.C64CharacterSet || + view.SpriteSet.Type == SpriteSet.SetType.MonoCharacterSet; + + StreamWriter stream = File.CreateText(fsel.Url.Path); + + stream.Write("sprite_data:"); + + int col = 0; + + StreamSpriteSet + (delegate (byte b) + { + if (col == 0) + { + stream.Write("\n\tbyte\t"); + } + else + { + stream.Write(","); + } + + stream.Write("{0}", b); + + if (++col == 8) + { + col = 0; + } + }, + view.SpriteSet, export_blank); + stream.Close(); } catch (Exception e) @@ -378,8 +495,12 @@ namespace SpriteEd [Export("exportC:")] private void ExportC(NSObject sender) { + if (NSApplication.SharedApplication.KeyWindow == null) + { + return; + } + NSSavePanel fsel = new NSSavePanel(); - ViewController view = ViewController; fsel.Title = "Export C"; fsel.AllowedFileTypes = new string[] {"c"}; @@ -389,7 +510,50 @@ namespace SpriteEd { try { - FileStream stream = File.Create(fsel.Url.Path); + ViewController view = ViewController; + + bool export_blank = view.SpriteSet.Type == SpriteSet.SetType.C64CharacterSet || + view.SpriteSet.Type == SpriteSet.SetType.MonoCharacterSet; + + StreamWriter stream = File.CreateText(fsel.Url.Path); + + stream.Write("unsigned char sprite_data[] =\n{"); + + int col = 0; + bool first_line = true; + + StreamSpriteSet + (delegate (byte b) + { + if (col == 0) + { + if (first_line) + { + stream.Write("\n\t"); + } + else + { + stream.Write(",\n\t"); + } + + first_line = false; + } + else + { + stream.Write(","); + } + + stream.Write("{0}", b); + + if (++col == 8) + { + col = 0; + } + }, + view.SpriteSet, export_blank); + + stream.Write("\n};"); + stream.Close(); } catch (Exception e) diff --git a/SpriteEd/Main.storyboard b/SpriteEd/Main.storyboard index e67a0aa..2130430 100644 --- a/SpriteEd/Main.storyboard +++ b/SpriteEd/Main.storyboard @@ -261,6 +261,9 @@ <menuItem title="C64 Colour Sprites" tag="5" id="lDX-nh-hex"> <modifierMask key="keyEquivalentModifierMask"/> </menuItem> + <menuItem title="Generic Mono Character Set" tag="6" id="2RF-FM-OnM"> + <modifierMask key="keyEquivalentModifierMask"/> + </menuItem> </items> </menu> <connections> @@ -334,15 +337,6 @@ DQ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> </textFieldCell> </textField> - <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Zfk-QG-gyF"> - <rect key="frame" x="100" y="143" width="55" height="21"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="kJF-32-OWQ"> - <font key="font" metaFont="system"/> - <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> - </textFieldCell> - </textField> <stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jiv-da-XAB"> <rect key="frame" x="17" y="113" width="19" height="28"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> @@ -421,14 +415,6 @@ Gw <action selector="OnHeightStepper:" target="Drs-be-wgu" id="6xw-Jo-8pI"/> </connections> </stepper> - <stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T6r-Pg-z3D"> - <rect key="frame" x="160" y="139" width="19" height="28"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <stepperCell key="cell" continuous="YES" alignment="left" minValue="2" maxValue="256" doubleValue="2" id="EGB-FJ-uRC"/> - <connections> - <action selector="OnPaletteSizeStepper:" target="Drs-be-wgu" id="uMI-aQ-GKi"/> - </connections> - </stepper> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TpZ-2l-0iA"> <rect key="frame" x="151" y="194" width="45" height="16"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> @@ -438,6 +424,27 @@ Gw <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> </textFieldCell> </textField> + <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iES-oQ-JDS"> + <rect key="frame" x="98" y="140" width="77" height="25"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <popUpButtonCell key="cell" type="push" title="2" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="2" imageScaling="proportionallyDown" inset="2" selectedItem="TSL-D5-3GY" id="LHV-Fd-UoG"> + <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + <menu key="menu" id="LDC-WN-8m9"> + <items> + <menuItem title="2" state="on" tag="2" id="TSL-D5-3GY"/> + <menuItem title="4" tag="4" id="29U-xK-YLw"/> + <menuItem title="16" tag="16" id="8BD-k8-N2o"/> + <menuItem title="256" tag="256" id="HMU-1c-SbQ"> + <modifierMask key="keyEquivalentModifierMask"/> + </menuItem> + </items> + </menu> + <connections> + <action selector="OnPaletteSize:" target="Drs-be-wgu" id="5nZ-l1-SY8"/> + </connections> + </popUpButtonCell> + </popUpButton> </subviews> </view> <connections> @@ -450,8 +457,7 @@ Gw <outlet property="m_HeightStepper" destination="nUG-p1-6V6" id="bvt-jD-1fR"/> <outlet property="m_OKButton" destination="GUU-WS-YNR" id="l4K-MC-XL7"/> <outlet property="m_PaletteNumber" destination="zll-pz-rRz" id="TTG-Wt-Fpj"/> - <outlet property="m_PaletteSize" destination="Zfk-QG-gyF" id="btM-HG-XiM"/> - <outlet property="m_PaletteSizeStepper" destination="T6r-Pg-z3D" id="L2U-pE-SGZ"/> + <outlet property="m_PaletteSize" destination="LHV-Fd-UoG" id="7AM-wj-YZR"/> <outlet property="m_PaletteStepper" destination="Jiv-da-XAB" id="d0e-4U-vXS"/> <outlet property="m_Width" destination="jjz-mG-zhc" id="cqV-xc-spz"/> <outlet property="m_WidthStepper" destination="w2C-jY-Ad9" id="8Px-ke-G6L"/> diff --git a/SpriteEd/SpriteSet.cs b/SpriteEd/SpriteSet.cs index 2f2c570..c472056 100644 --- a/SpriteEd/SpriteSet.cs +++ b/SpriteEd/SpriteSet.cs @@ -58,7 +58,12 @@ namespace SpriteEd /// <summary> /// Commodore 64 colour sprites. /// </summary> - C64ColourSprite + C64ColourSprite, + + /// <summary> + /// Generic mono character set. + /// </summary> + MonoCharacterSet } private const uint SET_SIZE = 256; diff --git a/SpriteEd/SpriteSetController.cs b/SpriteEd/SpriteSetController.cs index f8fed80..65f872d 100644 --- a/SpriteEd/SpriteSetController.cs +++ b/SpriteEd/SpriteSetController.cs @@ -35,7 +35,6 @@ namespace SpriteEd base.ViewDidLoad(); m_Width.IntValue = m_WidthStepper.IntValue; m_Height.IntValue = m_HeightStepper.IntValue; - m_PaletteSize.IntValue = m_PaletteSizeStepper.IntValue; m_palette = new Palette(2); m_palette[0] = new Colour(); m_palette[1] = new Colour(255, 255, 255); @@ -94,8 +93,7 @@ namespace SpriteEd m_palette = new Palette(2); m_palette[0] = new Colour(); m_palette[1] = new Colour(255, 255, 255); - m_PaletteSize.IntValue = (int)m_palette.Size; - m_PaletteSizeStepper.IntValue = m_PaletteSize.IntValue; + m_PaletteSize.SelectItemWithTag((nint)m_palette.Size); m_PaletteStepper.MaxValue = m_palette.Size - 1; OnPaletteStepper(m_PaletteStepper); } @@ -107,8 +105,7 @@ namespace SpriteEd m_palette[1] = new Colour(255, 0, 0); m_palette[2] = new Colour(0, 0, 255); m_palette[3] = new Colour(255, 255, 255); - m_PaletteSize.IntValue = (int)m_palette.Size; - m_PaletteSizeStepper.IntValue = m_PaletteSize.IntValue; + m_PaletteSize.SelectItemWithTag((nint)m_palette.Size); m_PaletteStepper.MaxValue = m_palette.Size - 1; OnPaletteStepper(m_PaletteStepper); } @@ -163,6 +160,14 @@ namespace SpriteEd m_DoubleWidth.State = NSCellStateValue.On; m_DoubleHeight.State = NSCellStateValue.Off; break; + + case SpriteSet.SetType.MonoCharacterSet: + SetSize(8, 8); + SetMonoPalette(); + m_CodePoints.SelectItem(0); + m_DoubleWidth.State = NSCellStateValue.Off; + m_DoubleHeight.State = NSCellStateValue.Off; + break; } } @@ -176,12 +181,10 @@ namespace SpriteEd m_Height.IntValue = m_HeightStepper.IntValue; } - partial void OnPaletteSizeStepper(NSObject sender) + partial void OnPaletteSize(NSObject sender) { - m_PaletteSize.IntValue = m_PaletteSizeStepper.IntValue; - Palette oldPalette = m_palette; - m_palette = new Palette((uint)m_PaletteSize.IntValue); + m_palette = new Palette((uint)m_PaletteSize.SelectedItem.Tag); for(uint f = 0; f < m_PaletteSize.IntValue; f++) { diff --git a/SpriteEd/SpriteSetController.designer.cs b/SpriteEd/SpriteSetController.designer.cs index 3a541f0..4b4ecf7 100644 --- a/SpriteEd/SpriteSetController.designer.cs +++ b/SpriteEd/SpriteSetController.designer.cs @@ -37,10 +37,7 @@ namespace SpriteEd AppKit.NSTextField m_PaletteNumber { get; set; } [Outlet] - AppKit.NSTextField m_PaletteSize { get; set; } - - [Outlet] - AppKit.NSStepper m_PaletteSizeStepper { get; set; } + AppKit.NSPopUpButtonCell m_PaletteSize { get; set; } [Outlet] AppKit.NSStepper m_PaletteStepper { get; set; } @@ -63,8 +60,8 @@ namespace SpriteEd [Action ("OnOK:")] partial void OnOK (Foundation.NSObject sender); - [Action ("OnPaletteSizeStepper:")] - partial void OnPaletteSizeStepper (Foundation.NSObject sender); + [Action ("OnPaletteSize:")] + partial void OnPaletteSize (Foundation.NSObject sender); [Action ("OnPaletteStepper:")] partial void OnPaletteStepper (Foundation.NSObject sender); @@ -117,16 +114,6 @@ namespace SpriteEd m_PaletteNumber = null; } - if (m_PaletteSize != null) { - m_PaletteSize.Dispose (); - m_PaletteSize = null; - } - - if (m_PaletteSizeStepper != null) { - m_PaletteSizeStepper.Dispose (); - m_PaletteSizeStepper = null; - } - if (m_PaletteStepper != null) { m_PaletteStepper.Dispose (); m_PaletteStepper = null; @@ -141,6 +128,11 @@ namespace SpriteEd m_WidthStepper.Dispose (); m_WidthStepper = null; } + + if (m_PaletteSize != null) { + m_PaletteSize.Dispose (); + m_PaletteSize = null; + } } } } |