Animations

This commit is contained in:
Denis Molony 2020-05-16 17:45:58 +10:00
parent 86af8eea39
commit 10658f09c2
5 changed files with 242 additions and 108 deletions

View File

@ -1,73 +1,89 @@
package com.bytezone.diskbrowser.applefile;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JPanel;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.HexFormatter;
public abstract class AbstractFile implements DataSource
{
protected String name;
public byte[] buffer;
protected AssemblerProgram assembler;
protected BufferedImage image;
protected int loadAddress;
public AbstractFile (String name, byte[] buffer)
{
this.name = name;
this.buffer = buffer;
}
@Override
public String getText () // Override this to get a tailored text representation
{
return "Name : " + name + "\n\nNo text description";
}
public String getName ()
{
return name;
}
@Override
public String getAssembler ()
{
if (buffer == null)
return "No buffer";
if (assembler == null)
this.assembler = new AssemblerProgram (name, buffer, loadAddress);
return assembler.getText ();
}
@Override
public String getHexDump ()
{
if (buffer == null || buffer.length == 0)
return "No buffer";
if (buffer.length <= 999999)
return HexFormatter.format (buffer, 0, buffer.length);
System.out.println ("**** truncating hex dump");
return HexFormatter.format (buffer, 0, 999999);
}
@Override
public BufferedImage getImage ()
{
return image;
}
@Override
public JComponent getComponent ()
{
JPanel panel = new JPanel ();
return panel;
}
package com.bytezone.diskbrowser.applefile;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JPanel;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.HexFormatter;
// -----------------------------------------------------------------------------------//
public abstract class AbstractFile implements DataSource
// -----------------------------------------------------------------------------------//
{
protected String name;
public byte[] buffer;
protected AssemblerProgram assembler;
protected BufferedImage image;
protected int loadAddress;
// ---------------------------------------------------------------------------------//
public AbstractFile (String name, byte[] buffer)
// ---------------------------------------------------------------------------------//
{
this.name = name;
this.buffer = buffer;
}
// ---------------------------------------------------------------------------------//
@Override
public String getText () // Override this to get a tailored text representation
// ---------------------------------------------------------------------------------//
{
return "Name : " + name + "\n\nNo text description";
}
// ---------------------------------------------------------------------------------//
public String getName ()
// ---------------------------------------------------------------------------------//
{
return name;
}
// ---------------------------------------------------------------------------------//
@Override
public String getAssembler ()
// ---------------------------------------------------------------------------------//
{
if (buffer == null)
return "No buffer";
if (assembler == null)
this.assembler = new AssemblerProgram (name, buffer, loadAddress);
return assembler.getText ();
}
// ---------------------------------------------------------------------------------//
@Override
public String getHexDump ()
// ---------------------------------------------------------------------------------//
{
if (buffer == null || buffer.length == 0)
return "No buffer";
if (buffer.length <= 999999)
return HexFormatter.format (buffer, 0, buffer.length);
System.out.println ("**** truncating hex dump");
return HexFormatter.format (buffer, 0, 999999);
}
// ---------------------------------------------------------------------------------//
@Override
public BufferedImage getImage ()
// ---------------------------------------------------------------------------------//
{
return image;
}
// ---------------------------------------------------------------------------------//
@Override
public JComponent getComponent ()
// ---------------------------------------------------------------------------------//
{
JPanel panel = new JPanel ();
return panel;
}
}

View File

@ -162,6 +162,13 @@ public abstract class HiResImage extends AbstractFile
this.eof = eof;
}
// ---------------------------------------------------------------------------------//
public boolean isAnimation ()
// ---------------------------------------------------------------------------------//
{
return fileType == ProdosConstants.FILE_TYPE_ANI;
}
// ---------------------------------------------------------------------------------//
protected void createImage ()
// ---------------------------------------------------------------------------------//

View File

@ -2,6 +2,8 @@ package com.bytezone.diskbrowser.applefile;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.prodos.ProdosConstants;
import com.bytezone.diskbrowser.utilities.HexFormatter;
@ -14,6 +16,10 @@ public class SHRPictureFile2 extends HiResImage
byte[] controlBytes;
int rows = 200; // may change
List<Integer> framePointers = new ArrayList<> ();
int frameNumber;
int delay;
// see Graphics & Animation.2mg
// ---------------------------------------------------------------------------------//
@ -33,9 +39,8 @@ public class SHRPictureFile2 extends HiResImage
break;
case ProdosConstants.FILE_TYPE_ANI:
this.auxType = 0x1000;
this.eof = 0x8000;
doPnt ();
doPic ();
doAnimation ();
break;
default:
@ -57,35 +62,20 @@ public class SHRPictureFile2 extends HiResImage
colorTables = new ColorTable[1];
colorTables[0] = new ColorTable (0, this.buffer, 0);
// if (false)
// {
// byte[] data = new byte[buffer.length - 0x222];
// System.arraycopy (buffer, 0x0222, data, 0, data.length);
// buffer = unpack (data);
// System.out.println ("paintworks");
// }
// else
// {
byte[] newBuffer = new byte[calculateBufferSize (buffer, 0x222)];
unpack (buffer, 0x222, buffer.length, newBuffer, 0);
buffer = newBuffer;
// }
rows = buffer.length / 160;
controlBytes = new byte[rows]; // all pointing to 0th color table
break;
case 1: // packed version of PIC/$00
// if (false)
// {
// buffer = unpack (buffer);
// }
// else
// {
newBuffer = new byte[calculateBufferSize (buffer, 0)];
unpack (buffer, 0, buffer.length, newBuffer, 0);
buffer = newBuffer;
// }
controlBytes = new byte[rows];
System.arraycopy (this.buffer, 32000, controlBytes, 0, controlBytes.length);
@ -104,14 +94,10 @@ public class SHRPictureFile2 extends HiResImage
// Apple IIGS Tech Note #46
// https://www.prepressure.com/library/file-formats/pict
// if (false)
// buffer = unpack (buffer);
// else
// {
newBuffer = new byte[calculateBufferSize (buffer, 0)];
unpack (buffer, 0, buffer.length, newBuffer, 0);
buffer = newBuffer;
// }
int mode = HexFormatter.unsignedShort (this.buffer, 0);
int rect1 = HexFormatter.unsignedLong (this.buffer, 2);
int rect2 = HexFormatter.unsignedLong (this.buffer, 6);
@ -136,18 +122,9 @@ public class SHRPictureFile2 extends HiResImage
colorTables[i].reverse ();
}
// if (false)
// {
// byte[] data = new byte[buffer.length - 6404]; // skip APP. and color tables
// System.arraycopy (buffer, 6404, data, 0, data.length);
// this.buffer = unpack (data);
// }
// else
// {
newBuffer = new byte[calculateBufferSize (buffer, 6404)];
unpack (buffer, 6404, buffer.length, newBuffer, 0);
buffer = newBuffer;
// }
break;
@ -172,6 +149,40 @@ public class SHRPictureFile2 extends HiResImage
}
}
// ---------------------------------------------------------------------------------//
private void doAnimation ()
// ---------------------------------------------------------------------------------//
{
// int len = HexFormatter.unsignedLong (buffer, 0x8000);
delay = HexFormatter.unsignedLong (buffer, 0x8004);
if (delay > 60)
delay = 10;
delay = delay * 1000 / 60;
// int offset = HexFormatter.unsignedLong (buffer, 0x8008);
// int blockLen = eof - 0x8008;
// System.out.printf ("Delay: %,d%n", delay);
// System.out.printf ("Blocklen: %,d%n", blockLen);
// System.out.printf ("Offset: %,d%n", offset);
// System.out.printf ("Len: %,d%n", len);
// System.out.println ();
int ptr = 0x800C;
int start = ptr;
while (ptr < buffer.length)
{
int off = HexFormatter.unsignedShort (buffer, ptr);
ptr += 4;
if (off == 0)
{
framePointers.add (start);
start = ptr;
}
}
}
// ---------------------------------------------------------------------------------//
private void doPic ()
// ---------------------------------------------------------------------------------//
@ -278,6 +289,34 @@ public class SHRPictureFile2 extends HiResImage
}
}
// ---------------------------------------------------------------------------------//
public void nextFrame ()
// ---------------------------------------------------------------------------------//
{
int ptr = framePointers.get (frameNumber++);
frameNumber %= framePointers.size ();
while (true)
{
int offset = HexFormatter.unsignedShort (buffer, ptr);
if (offset == 0)
break;
buffer[offset] = buffer[ptr + 2];
buffer[offset + 1] = buffer[ptr + 3];
ptr += 4;
}
createImage ();
}
// ---------------------------------------------------------------------------------//
public int getDelay ()
// ---------------------------------------------------------------------------------//
{
return delay;
}
// ---------------------------------------------------------------------------------//
@Override
public String getText ()

View File

@ -32,12 +32,13 @@ import com.bytezone.diskbrowser.applefile.HiResImage;
import com.bytezone.diskbrowser.applefile.Palette;
import com.bytezone.diskbrowser.applefile.PaletteFactory.CycleDirection;
import com.bytezone.diskbrowser.applefile.QuickDrawFont;
import com.bytezone.diskbrowser.applefile.SHRPictureFile2;
import com.bytezone.diskbrowser.applefile.VisicalcFile;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.SectorList;
// -----------------------------------------------------------------------------------//
class DataPanel extends JTabbedPane implements DiskSelectionListener,
public class DataPanel extends JTabbedPane implements DiskSelectionListener,
FileSelectionListener, SectorSelectionListener, FileNodeSelectionListener,
FontChangeListener, BasicPreferencesListener, AssemblerPreferencesListener
// -----------------------------------------------------------------------------------//
@ -64,6 +65,8 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
boolean assemblerTextValid;
DataSource currentDataSource;
private Animation animation;
final MenuHandler menuHandler;
// ---------------------------------------------------------------------------------//
@ -233,6 +236,17 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
}
}
// ---------------------------------------------------------------------------------//
public void update ()
// ---------------------------------------------------------------------------------//
{
if (currentDataSource instanceof HiResImage)
{
HiResImage image = (HiResImage) currentDataSource;
imagePanel.setImage (image.getImage ());
}
}
// ---------------------------------------------------------------------------------//
public void setDebug (boolean value)
// ---------------------------------------------------------------------------------//
@ -343,7 +357,16 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
{
((HiResImage) dataSource).checkPalette ();
image = dataSource.getImage ();
if (((HiResImage) dataSource).isAnimation ())
{
if (animation != null)
animation.cancel ();
animation = new Animation ((SHRPictureFile2) dataSource);
animation.start ();
// System.out.println ("new animation");
}
}
imagePanel.setImage (image);
imagePane.setViewportView (imagePanel);
@ -354,6 +377,7 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
add (imagePane, "Formatted", 0);
setSelectedIndex (selected);
imageVisible = true;
}
}
}
@ -370,6 +394,12 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
setSelectedIndex (selected);
imageVisible = false;
}
if (animation != null)
{
animation.cancel ();
animation = null;
}
}
// ---------------------------------------------------------------------------------//
@ -521,4 +551,43 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
if (currentDataSource instanceof AssemblerProgram)
setDataSource (currentDataSource);
}
// ---------------------------------------------------------------------------------//
class Animation extends Thread
// ---------------------------------------------------------------------------------//
{
boolean running;
SHRPictureFile2 image;
int delay;
public Animation (SHRPictureFile2 image)
{
this.image = image;
delay = image.getDelay ();
}
public void cancel ()
{
running = false;
}
@Override
public void run ()
{
running = true;
try
{
while (running)
{
sleep (delay);
image.nextFrame ();
update ();
}
}
catch (InterruptedException e)
{
e.printStackTrace ();
}
}
}
}

View File

@ -418,7 +418,6 @@ class FileEntry extends CatalogEntry implements ProdosConstants
break;
case FILE_TYPE_PNT:
case FILE_TYPE_ANI:
if (auxType == 2)
file = new SHRPictureFile1 (name, exactBuffer, fileType, auxType, endOfFile);
else if (endOfFile < 0x222)
@ -427,6 +426,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants
file = new SHRPictureFile2 (name, exactBuffer, fileType, auxType, endOfFile);
break;
case FILE_TYPE_ANI:
file = new SHRPictureFile2 (name, exactBuffer, fileType, auxType, endOfFile);
break;
case FILE_TYPE_PIC:
file = new SHRPictureFile2 (name, exactBuffer, fileType, auxType, endOfFile);
break;