colour quirks

This commit is contained in:
Denis Molony 2016-02-21 11:00:57 +11:00
parent 98a5d273d1
commit d0ab7b9a45
5 changed files with 182 additions and 147 deletions

View File

@ -11,16 +11,25 @@ import com.bytezone.diskbrowser.HexFormatter;
public class HiResImage extends AbstractFile
{
private static final int[][] colours = { { 0x000000, 0xBB66FF, 0x00FF00, 0xFFFFFF },
{ 0x000000, 0x0000FF, 0xFF0000, 0xFFFFFF } };
private static final int WHITE = 0xFFFFFF;
private static final int BLACK = 0x000000;
private static final int RED = 0xFF0000;
private static final int GREEN = 0x00FF00;
private static final int BLUE = 0x0000FF;
private static final int VIOLET = 0xBB66FF;
private static final int[][] colours = { { VIOLET, GREEN }, { BLUE, RED } };
int fileType;
int auxType;
byte[] unpackedBuffer;
private static int[] line = new int[280];
private int fileType;
private int auxType;
private byte[] unpackedBuffer;
private static boolean colourQuirks;
public HiResImage (String name, byte[] buffer)
{
super (name, buffer);
if (name.equals ("FLY LOGO") || name.equals ("BIGBAT.PAC"))
{
this.buffer = unscrunch (buffer);
@ -50,6 +59,20 @@ public class HiResImage extends AbstractFile
}
}
public static void setDefaultColourQuirks (boolean value)
{
colourQuirks = value;
}
public void setColourQuirks (boolean value)
{
if (colourQuirks == value)
return;
colourQuirks = value;
drawColour (buffer);
}
private void drawMonochrome (byte[] buffer)
{
int rows = buffer.length <= 8192 ? 192 : 384;
@ -91,74 +114,6 @@ public class HiResImage extends AbstractFile
image = new BufferedImage (280, rows, BufferedImage.TYPE_INT_RGB);
DataBuffer db = image.getRaster ().getDataBuffer ();
int[][] colours = { { 0xBB66FF, 0x00FF00 }, { 0x0000FF, 0xFF0000 } };
int element = 0;
int[] line = new int[280];
int linePtr = 0;
for (int z = 0; z < rows / 192; z++)
{
int zz = z * 0x2000;
for (int i = 0; i < 3; i++)
{
int ii = zz + i * 0x28;
for (int j = 0; j < 8; j++)
{
int jj = ii + j * 0x80;
for (int k = 0; k < 8; k++)
{
int base = jj + k * 0x400;
int max = Math.min (base + 40, buffer.length);
for (int ptr = base; ptr < max; ptr++)
{
int colourBit = (buffer[ptr] & 0x80) >> 7;
int value = buffer[ptr] & 0x7F;
for (int px = 0; px < 7; px++)
{
int val = (value >> px) & 0x01;
int column = (ptr + px) % 2;
line[linePtr++] = val == 0 ? 0 : colours[colourBit][column];
}
}
// convert ALL consecutive ON pixels to white
for (int x = 0; x < line.length - 1; x++)
if (line[x] != 0 && line[x + 1] != 0)
line[x] = line[x + 1] = 0xFFFFFF;
// convert single coloured pixels to double - this can be ugly
if (false)
{
for (int x = 0; x < line.length - 1; x += 2)
if (line[x] != 0 && line[x] != 0xFFFFFF && line[x + 1] == 0)
line[x + 1] = line[x];
else if (line[x] == 0 && line[x + 1] != 0 && line[x + 1] != 0xFFFFFF)
line[x] = line[x + 1];
}
for (int pixel : line)
db.setElem (element++, pixel);
linePtr = 0;
}
}
}
}
}
private void drawSolidColour (byte[] buffer)
{
int rows = buffer.length <= 8192 ? 192 : 384;
image = new BufferedImage (280, rows, BufferedImage.TYPE_INT_RGB);
DataBuffer db = image.getRaster ().getDataBuffer ();
int[][] colours = { { 0x000000, 0xBB66FF, 0x00FF00, 0xFFFFFF },
{ 0x000000, 0x0000FF, 0xFF0000, 0xFFFFFF } };
int element = 0;
for (int z = 0; z < rows / 192; z++)
@ -167,35 +122,71 @@ public class HiResImage extends AbstractFile
for (int k = 0; k < 8; k++)
{
int base = i * 0x28 + j * 0x80 + k * 0x400 + z * 0x2000;
int max = Math.min (base + 40, buffer.length);
for (int ptr = base; ptr < max; ptr += 2)
{
int colourBit1 = (buffer[ptr] & 0x80) >> 7;
int colourBit2 = (buffer[ptr + 1] & 0x80) >> 7;
int value = ((buffer[ptr + 1] & 0x7F) << 7) + (buffer[ptr] & 0x7F);
for (int px = 0; px < 7; px++)
{
int val = value & 0x03;
value >>= 2;
int colour = 0;
if (px <= 2)
colour = colours[colourBit1][val];
else if (px == 3)
colour = colours[val >= 2 ? colourBit1 : colourBit2][val];
else
colour = colours[colourBit2][val];
db.setElem (element++, colour);
db.setElem (element++, colour);
}
}
element = drawLine (db, element, base);
}
}
private int drawLine (DataBuffer db, int element, int base)
{
int max = Math.min (base + 40, buffer.length);
int linePtr = 0;
for (int ptr = base; ptr < max; ptr++)
{
int colourBit = (buffer[ptr] & 0x80) >> 7;
int value = buffer[ptr] & 0x7F;
for (int px = 0; px < 7; px++)
{
int val = (value >> px) & 0x01;
int column = (ptr + px) % 2;
line[linePtr++] = val == 0 ? 0 : colours[colourBit][column];
}
}
// convert ALL consecutive ON pixels to white
for (int x = 0; x < line.length - 1; x++)
if (line[x] != BLACK && line[x + 1] != BLACK)
line[x] = line[x + 1] = WHITE;
// convert WOZ quirks
if (colourQuirks)
{
for (int x = 0; x < line.length - 4; x++)
{
if (line[x + 1] == BLACK)
{
// V-B-V-B -> V-V-V-B
if (line[x + 3] == BLACK && line[x] == line[x + 2] && line[x] != BLACK
&& line[x] != WHITE)
line[x + 1] = line[x];
// V-B-W-W -> V-V-W-W
if (line[x] != BLACK && line[x] != WHITE && line[x + 3] == WHITE
&& line[x + 2] == WHITE)
line[x + 1] = line[x];
}
if (line[x + 2] == BLACK)
{
// B-G-B-G -> B-G-G-G
if (line[x] == BLACK && line[x + 1] == line[x + 3] && line[x + 1] != WHITE
&& line[x + 1] != BLACK)
line[x + 2] = line[x + 1];
// W-W-B-G -> W-W-G-G
if (line[x] == WHITE && line[x + 1] == WHITE && line[x + 3] != BLACK
&& line[x + 3] != WHITE)
line[x + 2] = line[x + 3];
}
}
}
for (int pixel : line)
db.setElem (element++, pixel);
return element;
}
private void makeScreen2 (byte[] buffer)
{
// System.out.println (HexFormatter.format (buffer, 32000, 640));

View File

@ -0,0 +1,29 @@
package com.bytezone.diskbrowser.gui;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
public class ColourQuirksAction extends AbstractAction
{
private final DataPanel owner;
public ColourQuirksAction (DataPanel owner)
{
super ("Colour quirks");
putValue (Action.SHORT_DESCRIPTION, "Display pixels like a TV screen");
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt Q"));
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_Q);
this.owner = owner;
}
@Override
public void actionPerformed (ActionEvent e)
{
owner.setColourQuirks (((JMenuItem) e.getSource ()).isSelected ());
}
}

View File

@ -1,28 +1,18 @@
package com.bytezone.diskbrowser.gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.prefs.Preferences;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.bytezone.common.FontAction.FontChangeEvent;
import com.bytezone.common.FontAction.FontChangeListener;
import com.bytezone.diskbrowser.applefile.HiResImage;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.SectorList;
@ -41,7 +31,7 @@ class DataPanel extends JTabbedPane
JScrollPane imagePane;
JTextArea formattedText;
ImagePanel imagePanel;// internal class
ImagePanel imagePanel; // internal class
boolean imageVisible = false;
@ -57,10 +47,11 @@ class DataPanel extends JTabbedPane
public DataPanel (MenuHandler mh, Preferences prefs)
{
// String dataFontName =
// prefs.get (PreferencesDialog.prefsDataFont, PreferencesDialog.defaultFontName);
// prefs.get (PreferencesDialog.prefsDataFont, PreferencesDialog.defaultFontName);
// System.out.println (dataFontName);
// int dataFontSize =
// prefs.getInt (PreferencesDialog.prefsDataFontSize, PreferencesDialog.defaultFontSize);
// prefs.getInt (PreferencesDialog.prefsDataFontSize,
// PreferencesDialog.defaultFontSize);
// font = new Font (dataFontName, Font.PLAIN, dataFontSize);
this.menuHandler = mh;
@ -133,6 +124,17 @@ class DataPanel extends JTabbedPane
});
mh.lineWrapItem.setAction (new LineWrapAction (formattedText));
mh.colourQuirksItem.setAction (new ColourQuirksAction (this));
}
public void setColourQuirks (boolean value)
{
if (currentDataSource instanceof HiResImage)
{
HiResImage image = (HiResImage) currentDataSource;
image.setColourQuirks (value);
imagePanel.setImage (image.getImage ());
}
}
private void setTabsFont (Font font)
@ -158,7 +160,7 @@ class DataPanel extends JTabbedPane
JScrollPane outputScrollPane =
new JScrollPane (outputPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
outputScrollPane.setBorder (null);// remove the ugly default border
outputScrollPane.setBorder (null); // remove the ugly default border
add (outputScrollPane, tabName);
return outputScrollPane;
}
@ -171,7 +173,7 @@ class DataPanel extends JTabbedPane
formattedText.setText ("");
hexText.setText ("");
disassemblyText.setText ("");
checkImage ();
removeImage ();
return;
}
@ -206,9 +208,7 @@ class DataPanel extends JTabbedPane
BufferedImage image = dataSource.getImage ();
if (image == null)
{
checkImage ();
}
removeImage ();
else
{
imagePanel.setImage (image);
@ -224,7 +224,7 @@ class DataPanel extends JTabbedPane
}
}
private void checkImage ()
private void removeImage ()
{
if (imageVisible)
{
@ -326,7 +326,8 @@ class DataPanel extends JTabbedPane
// if (evt.getKey ().equals (PreferencesDialog.prefsDataFont))
// font = new Font (evt.getNewValue (), Font.PLAIN, font.getSize ());
// if (evt.getKey ().equals (PreferencesDialog.prefsDataFontSize))
// font = new Font (font.getFontName (), Font.PLAIN, Integer.parseInt (evt.getNewValue ()));
// font = new Font (font.getFontName (),
// Font.PLAIN, Integer.parseInt (evt.getNewValue ()));
// setTabsFont (font);
// }

View File

@ -47,18 +47,21 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
// create and add the right-hand disk layout panel
DiskLayoutPanel diskLayoutPanel = new DiskLayoutPanel ();
JPanel layoutBorderPanel = addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
JPanel layoutBorderPanel =
addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
// create actions
RootDirectoryAction rootDirectoryAction = new RootDirectoryAction (null, catalogPanel);
RootDirectoryAction rootDirectoryAction =
new RootDirectoryAction (null, catalogPanel);
RefreshTreeAction refreshTreeAction = new RefreshTreeAction (catalogPanel);
// PreferencesAction preferencesAction = new PreferencesAction (this, prefs);
AbstractAction print = new PrintAction (dataPanel);
AboutAction aboutAction = new AboutAction ();
HideCatalogAction hideCatalogAction = new HideCatalogAction (this, catalogBorderPanel);
HideCatalogAction hideCatalogAction =
new HideCatalogAction (this, catalogBorderPanel);
HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
ShowFreeSectorsAction showFreeAction =
new ShowFreeSectorsAction (menuHandler, diskLayoutPanel);
new ShowFreeSectorsAction (menuHandler, diskLayoutPanel);
DuplicateAction duplicateAction = new DuplicateAction ();
CloseTabAction closeTabAction = new CloseTabAction (catalogPanel);
@ -149,8 +152,8 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
@Override
public void diskSelected (DiskSelectedEvent e)
{
setTitle (windowTitle + e.getFormattedDisk () == null ? "" : e.getFormattedDisk ()
.getName ());
setTitle (windowTitle + e.getFormattedDisk () == null ? ""
: e.getFormattedDisk ().getName ());
}
public static void main (String[] args)

View File

@ -7,17 +7,23 @@ import java.util.prefs.Preferences;
import javax.swing.*;
import com.bytezone.common.*;
import com.bytezone.common.EnvironmentAction;
import com.bytezone.common.FontAction;
import com.bytezone.common.OSXAdapter;
import com.bytezone.common.Platform;
import com.bytezone.common.QuitAction.QuitListener;
import com.bytezone.diskbrowser.applefile.HiResImage;
import com.bytezone.diskbrowser.disk.DataDisk;
import com.bytezone.diskbrowser.disk.FormattedDisk;
public class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitListener
public class MenuHandler
implements DiskSelectionListener, FileSelectionListener, QuitListener
{
private static final String PREFS_LINE_WRAP = "line wrap";
private static final String PREFS_SHOW_CATALOG = "show catalog";
private static final String PREFS_SHOW_LAYOUT = "show layout";
private static final String PREFS_SHOW_FREE_SECTORS = "show free sectors";
private static final String PREFS_COLOUR_QUIRKS = "colour quirks";
FormattedDisk currentDisk;
@ -40,8 +46,8 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
FontAction fontAction;
// Format menu items
JMenuItem lineWrapItem = new JCheckBoxMenuItem ("Line wrap");
JMenuItem showLayoutItem = new JCheckBoxMenuItem ("Show layout panel");
final JMenuItem lineWrapItem = new JCheckBoxMenuItem ("Line wrap");
final JMenuItem showLayoutItem = new JCheckBoxMenuItem ("Show layout panel");
JMenuItem showCatalogItem = new JCheckBoxMenuItem ("Show catalog panel");
JMenuItem showFreeSectorsItem = new JCheckBoxMenuItem ("Show free sectors");
@ -52,6 +58,8 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
JMenuItem interleave2Item = new JRadioButtonMenuItem (new InterleaveAction (2));
JMenuItem interleave3Item = new JRadioButtonMenuItem (new InterleaveAction (3));
JMenuItem colourQuirksItem = new JCheckBoxMenuItem ("Colour quirks");
public MenuHandler (Preferences prefs)
{
menuBar.add (fileMenu);
@ -73,9 +81,9 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
JMenuItem fontItem = new JMenuItem (fontAction);
fileMenu.add (fontItem);
fontAction.setSampleText ("120 FOR Z = 14 TO 24:\n" + " VTAB 5:\n" + " HTAB Z:\n"
+ " PRINT AB$:\n" + " FOR TI = 1 TO 50:\n" + " NEXT :\n" + " POKE 0,Z + 40:\n"
+ " POKE 1,9:\n" + " CALL MU:\n" + " VTAB 5:\n" + " HTAB Z:\n"
+ " PRINT SPC(12):\n" + "NEXT :\n" + "VTAB 5:\n" + "HTAB 24:\n" + "PRINT AB$\n");
+ " PRINT AB$:\n" + " FOR TI = 1 TO 50:\n" + " NEXT :\n" + " POKE 0,Z + 40:\n"
+ " POKE 1,9:\n" + " CALL MU:\n" + " VTAB 5:\n" + " HTAB Z:\n"
+ " PRINT SPC(12):\n" + "NEXT :\n" + "VTAB 5:\n" + "HTAB 24:\n" + "PRINT AB$\n");
if (false)
{
@ -97,6 +105,8 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
formatMenu.addSeparator ();
formatMenu.add (sector256Item);
formatMenu.add (sector512Item);
formatMenu.addSeparator ();
formatMenu.add (colourQuirksItem);
helpMenu.add (new JMenuItem (new EnvironmentAction ()));
@ -105,10 +115,6 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
sector512Item.setActionCommand ("512");
sector512Item.setAccelerator (KeyStroke.getKeyStroke ("alt 5"));
lineWrapItem.setAccelerator (KeyStroke.getKeyStroke ("alt W"));
printItem.setAccelerator (KeyStroke.getKeyStroke ("control P"));
// ButtonGroup dosGroup = new ButtonGroup ();
ButtonGroup sectorGroup = new ButtonGroup ();
ButtonGroup interleaveGroup = new ButtonGroup ();
@ -126,6 +132,8 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
showLayoutItem.setSelected (prefs.getBoolean (PREFS_SHOW_LAYOUT, true));
showCatalogItem.setSelected (prefs.getBoolean (PREFS_SHOW_CATALOG, true));
showFreeSectorsItem.setSelected (prefs.getBoolean (PREFS_SHOW_FREE_SECTORS, false));
colourQuirksItem.setSelected (prefs.getBoolean (PREFS_COLOUR_QUIRKS, false));
HiResImage.setDefaultColourQuirks (colourQuirksItem.isSelected ());
}
void addHelpMenuAction (Action action, String functionName)
@ -135,14 +143,11 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
try
{
if (functionName.equals ("about"))
OSXAdapter.setAboutHandler (action,
action.getClass ().getDeclaredMethod (functionName,
(Class[]) null));
OSXAdapter.setAboutHandler (action, action.getClass ()
.getDeclaredMethod (functionName, (Class[]) null));
else if (functionName.equals ("prefs"))
OSXAdapter.setPreferencesHandler (action,
action.getClass ()
.getDeclaredMethod (functionName,
(Class[]) null));
OSXAdapter.setPreferencesHandler (action, action.getClass ()
.getDeclaredMethod (functionName, (Class[]) null));
}
catch (Exception e)
{
@ -182,6 +187,7 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
prefs.putBoolean (PREFS_SHOW_LAYOUT, showLayoutItem.isSelected ());
prefs.putBoolean (PREFS_SHOW_CATALOG, showCatalogItem.isSelected ());
prefs.putBoolean (PREFS_SHOW_FREE_SECTORS, showFreeSectorsItem.isSelected ());
prefs.putBoolean (PREFS_COLOUR_QUIRKS, colourQuirksItem.isSelected ());
}
@Override
@ -247,7 +253,12 @@ public class MenuHandler implements DiskSelectionListener, FileSelectionListener
}
@Override
public void restore (Preferences preferences)
public void restore (Preferences prefs)
{
// lineWrapItem.setSelected (prefs.getBoolean (PREFS_LINE_WRAP, true));
// showLayoutItem.setSelected (prefs.getBoolean (PREFS_SHOW_LAYOUT, true));
// showCatalogItem.setSelected (prefs.getBoolean (PREFS_SHOW_CATALOG, true));
// showFreeSectorsItem.setSelected (prefs.getBoolean (PREFS_SHOW_FREE_SECTORS, false));
// colourQuirksItem.setSelected (prefs.getBoolean (PREFS_COLOUR_QUIRKS, false));
}
}