scaled images

This commit is contained in:
Denis Molony 2020-04-09 19:47:30 +10:00
parent 2a85fa59e4
commit 6df5ff2826
9 changed files with 173 additions and 165 deletions

View File

@ -13,4 +13,18 @@ public interface DiskAddress extends Comparable<DiskAddress>
public Disk getDisk (); public Disk getDisk ();
public boolean matches (DiskAddress other); public boolean matches (DiskAddress other);
// ---------------------------------------------------------------------------------//
public default byte[] readSector ()
// ---------------------------------------------------------------------------------//
{
return getDisk ().readSector (this);
}
// ---------------------------------------------------------------------------------//
public default boolean isValidAddress ()
// ---------------------------------------------------------------------------------//
{
return getDisk ().isValidAddress (this);
}
} }

View File

@ -598,7 +598,6 @@ public class DiskFactory
if (tracks * 4096 != file.length ()) if (tracks * 4096 != file.length ())
{ {
System.out.println ("*** extended ***"); // System Addons.hdv System.out.println ("*** extended ***"); // System Addons.hdv
// System.out.println (tracks);
} }
AppleDisk disk = new AppleDisk (file, tracks, 8); AppleDisk disk = new AppleDisk (file, tracks, 8);
if (ProdosDisk.isCorrectFormat (disk)) if (ProdosDisk.isCorrectFormat (disk))
@ -669,14 +668,18 @@ public class DiskFactory
try try
{ {
AppleDisk disk = new AppleDisk (file, 0, 0); AppleDisk disk = new AppleDisk (file, 0, 0);
if (disk.getTotalBlocks () > 0 && ProdosDisk.isCorrectFormat (disk)) if (disk.getTotalBlocks () > 0)
return new ProdosDisk (disk); {
if (ProdosDisk.isCorrectFormat (disk))
return new ProdosDisk (disk);
// switch sector size if (file.length () == 143424)
disk.switchToDos (); {
// System.out.println (disk); disk.switchToDos (); // switch sector size
if (disk.getTotalBlocks () > 0 && DosDisk.isCorrectFormat (disk)) if (DosDisk.isCorrectFormat (disk))
return new DosDisk (disk); return new DosDisk (disk);
}
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -684,7 +687,7 @@ public class DiskFactory
// System.out.println (e); // System.out.println (e);
} }
if (debug) if (debug)
System.out.println ("Not a Prodos 2mg disk"); System.out.println ("Not a 2mg disk");
return null; return null;
} }

View File

@ -28,13 +28,22 @@ class CatalogEntry extends AbstractCatalogEntry
loop: while (da.getBlock () > 0 || ((AppleDiskAddress) da).zeroFlag ()) loop: while (da.getBlock () > 0 || ((AppleDiskAddress) da).zeroFlag ())
{ {
if (dosDisk.stillAvailable (da)) if (dosDisk.stillAvailable (da))
dosDisk.sectorTypes[da.getBlock ()] = dosDisk.tsListSector; {
if (isValidCatalogSector (da))
dosDisk.sectorTypes[da.getBlock ()] = dosDisk.tsListSector;
else
{
System.out.printf ("Attempt to assign invalid TS sector " + ": %s from %s%n",
da, name);
break;
}
}
else else
{ {
System.out.printf ( System.out.printf (
"Attempt to assign TS sector to occupied sector " + ": %s from %s%n", da, "Attempt to assign TS sector to occupied sector " + ": %s from %s%n", da,
name); name);
// break; break;
} }
tsSectors.add (da); tsSectors.add (da);
byte[] sectorBuffer = disk.readSector (da); byte[] sectorBuffer = disk.readSector (da);
@ -131,6 +140,20 @@ class CatalogEntry extends AbstractCatalogEntry
} }
} }
// ---------------------------------------------------------------------------------//
private boolean isValidCatalogSector (DiskAddress da)
// ---------------------------------------------------------------------------------//
{
byte[] buffer = da.readSector ();
if (!da.getDisk ().isValidAddress (buffer[1], buffer[2]))
return false;
if (buffer[4] != 0)
return false;
return true;
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
String getDetails () String getDetails ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//

View File

@ -129,7 +129,7 @@ class DosCatalogSector extends AbstractSector
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
private String getName (byte[] buffer, int offset, int length) static String getName (byte[] buffer, int offset, int length)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();

View File

@ -45,69 +45,11 @@ class DosVTOCSector extends AbstractSector
public String createText () public String createText ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
return dosVersion <= 3 ? createDosText () : createDos4Text (); return dosVersion <= 3 ? createDos3Text () : createDos4Text ();
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
private String createDos4Text () private String createDos3Text ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = getHeader ("DOS 4 VTOC Sector");
addText (text, buffer, 0, 1, "Not used");
addText (text, buffer, 1, 2, "First directory track/sector");
addText (text, buffer, 3, 1, "DOS release number");
addText (text, buffer, 4, 1, "Build number");
addText (text, buffer, 5, 1, "Ram DOS " + (char) (buffer[5] & 0x7F));
addTextAndDecimal (text, buffer, 6, 1, "Diskette volume");
String diskType =
buffer[7] == (byte) 0xC4 ? " = Data" : buffer[7] == (byte) 0xC2 ? " = Boot" : "";
addText (text, buffer, 7, 1, "Volume type: " + (char) (buffer[7] & 0x7F) + diskType);
int ptr = 8;
addText (text, buffer, ptr, 4, "Volume name: " + getName (buffer, ptr));
for (int j = 4; j < 24; j += 4)
addText (text, buffer, ptr + j, 4, "");
addText (text, buffer, 0x20, 3,
"Date/time initialised: " + Utility.getDateTime (buffer, 0x20));
addText (text, buffer, 0x23, 3, "");
addText (text, buffer, 0x26, 1, "VTOC Phase");
addTextAndDecimal (text, buffer, 0x27, 1, "Maximum TS pairs");
addText (text, buffer, 0x28, 2, "Volume library");
addText (text, buffer, 0x2A, 3,
"Date/time modified: " + Utility.getDateTime (buffer, 0x2A));
addText (text, buffer, 0x2D, 3, "");
addTextAndDecimal (text, buffer, 0x30, 1, "Last allocated track");
addText (text, buffer, 0x31, 1, "Direction to look when allocating the next file");
addText (text, buffer, 0x32, 2, "Not used");
addTextAndDecimal (text, buffer, 0x34, 1, "Maximum tracks");
addTextAndDecimal (text, buffer, 0x35, 1, "Maximum sectors");
addTextAndDecimal (text, buffer, 0x36, 2, "Bytes per sector");
boolean bootSectorEmpty = parentDisk.getDisk ().isSectorEmpty (0);
int firstSector = 0x38;
int max = maxTracks * 4 + firstSector;
for (int i = firstSector; i < max; i += 4)
{
String extra = "";
if (i == firstSector && bootSectorEmpty)
extra = "(unusable)";
else if (i == 124)
extra = "(VTOC and Catalog)";
addText (text, buffer, i, 4, String.format ("Track %02X %s %s",
(i - firstSector) / 4, getBitmap (buffer, i), extra));
}
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
// ---------------------------------------------------------------------------------//
private String createDosText ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
StringBuilder text = getHeader ("VTOC Sector"); StringBuilder text = getHeader ("VTOC Sector");
@ -153,33 +95,64 @@ class DosVTOCSector extends AbstractSector
return text.toString (); return text.toString ();
} }
// private String getBitmap (byte left, byte right) // ---------------------------------------------------------------------------------//
// { private String createDos4Text ()
// StringBuilder text = new StringBuilder (); // ---------------------------------------------------------------------------------//
// {
// int base = maxSectors == 13 ? 3 : 0; StringBuilder text = getHeader ("DOS 4 VTOC Sector");
// right >>= base; addText (text, buffer, 0, 1, "Not used");
// addText (text, buffer, 1, 2, "First directory track/sector");
// for (int i = base; i < 8; i++) addText (text, buffer, 3, 1, "DOS release number");
// { addText (text, buffer, 4, 1, "Build number");
// if ((right & 0x01) == 1) addText (text, buffer, 5, 1, "Ram DOS " + (char) (buffer[5] & 0x7F));
// text.append (".");
// else addTextAndDecimal (text, buffer, 6, 1, "Diskette volume");
// text.append ("X"); String diskType =
// right >>= 1; buffer[7] == (byte) 0xC4 ? " = Data" : buffer[7] == (byte) 0xC2 ? " = Boot" : "";
// } addText (text, buffer, 7, 1, "Volume type: " + (char) (buffer[7] & 0x7F) + diskType);
//
// for (int i = 0; i < 8; i++) int ptr = 8;
// { addText (text, buffer, ptr, 4,
// if ((left & 0x01) == 1) "Volume name: " + DosCatalogSector.getName (buffer, ptr, 30));
// text.append ("."); for (int j = 4; j < 24; j += 4)
// else addText (text, buffer, ptr + j, 4, "");
// text.append ("X");
// left >>= 1; addText (text, buffer, 0x20, 3,
// } "Date/time initialised: " + Utility.getDateTime (buffer, 0x20));
// addText (text, buffer, 0x23, 3, "");
// return text.toString (); addText (text, buffer, 0x26, 1, "VTOC Phase");
// }
addTextAndDecimal (text, buffer, 0x27, 1, "Maximum TS pairs");
addText (text, buffer, 0x28, 2, "Volume library");
addText (text, buffer, 0x2A, 3,
"Date/time modified: " + Utility.getDateTime (buffer, 0x2A));
addText (text, buffer, 0x2D, 3, "");
addTextAndDecimal (text, buffer, 0x30, 1, "Last allocated track");
addText (text, buffer, 0x31, 1, "Direction to look when allocating the next file");
addText (text, buffer, 0x32, 2, "Not used");
addTextAndDecimal (text, buffer, 0x34, 1, "Maximum tracks");
addTextAndDecimal (text, buffer, 0x35, 1, "Maximum sectors");
addTextAndDecimal (text, buffer, 0x36, 2, "Bytes per sector");
boolean bootSectorEmpty = parentDisk.getDisk ().isSectorEmpty (0);
int firstSector = 0x38;
int max = maxTracks * 4 + firstSector;
for (int i = firstSector; i < max; i += 4)
{
String extra = "";
if (i == firstSector && bootSectorEmpty)
extra = "(unusable)";
else if (i == 124)
extra = "(VTOC and Catalog)";
addText (text, buffer, i, 4, String.format ("Track %02X %s %s",
(i - firstSector) / 4, getBitmap (buffer, i), extra));
}
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
private String getBitmap (byte[] buffer, int offset) private String getBitmap (byte[] buffer, int offset)
@ -209,12 +182,10 @@ class DosVTOCSector extends AbstractSector
int track = (i - firstSector) / 4; int track = (i - firstSector) / 4;
String bits = getBitmap (buffer, i); String bits = getBitmap (buffer, i);
// System.out.printf ("%08X %s%n", track, bits);
int blockNo = track * maxSectors; int blockNo = track * maxSectors;
char[] chars = bits.toCharArray (); char[] chars = bits.toCharArray ();
for (int sector = 0; sector < maxSectors; sector++) for (int sector = 0; sector < maxSectors; sector++)
{ {
// System.out.printf ("%3d %s%n", blockNo, chars[sector]);
if (chars[sector] == '.') if (chars[sector] == '.')
{ {
parentDisk.setSectorFree (blockNo, true); parentDisk.setSectorFree (blockNo, true);
@ -230,66 +201,6 @@ class DosVTOCSector extends AbstractSector
} }
} }
// private void flagSectors ()
// {
// int block = 0;
// int base = maxSectors == 13 ? 3 : 0;
// int firstSector = 0x38;
// int max = maxTracks * 4 + firstSector;
// for (int i = firstSector; i < max; i += 4)
// {
// block = check (buffer[i + 1], block, base);
// block = check (buffer[i], block, 0);
// }
// }
// private int check (byte b, int block, int base)
// {
// b >>= base;
// for (int i = base; i < 8; i++)
// {
// if ((b & 0x01) == 1)
// {
// parentDisk.setSectorFree (block, true);
// ++freeSectors;
// }
// else
// {
// parentDisk.setSectorFree (block, false);
// ++usedSectors;
// }
// block++;
// b >>= 1;
// }
// return block;
// }
// duplicate of DosCatalogSector.getName()
// ---------------------------------------------------------------------------------//
private String getName (byte[] buffer, int offset)
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
int max = 24;
for (int i = 0; i < max; i++)
{
int c = buffer[i + offset] & 0xFF;
if (c == 136)
{
if (text.length () > 0)
text.deleteCharAt (text.length () - 1);
continue;
}
if (c > 127)
c -= c < 160 ? 64 : 128;
if (c < 32) // non-printable
text.append ("^" + (char) (c + 64));
else
text.append ((char) c); // standard ascii
}
return text.toString ();
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@Override @Override
public String toString () public String toString ()

View File

@ -221,6 +221,18 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
} }
} }
// ---------------------------------------------------------------------------------//
public void setScale (double scale)
// ---------------------------------------------------------------------------------//
{
imagePanel.setScale (scale);
if (currentDataSource instanceof HiResImage)
{
HiResImage image = (HiResImage) currentDataSource;
imagePanel.setImage (image.getImage ());
}
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public void setDebug (boolean value) public void setDebug (boolean value)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -374,13 +386,18 @@ class DataPanel extends JTabbedPane implements DiskSelectionListener,
{ {
private BufferedImage image; private BufferedImage image;
private double scale = 1; private double scale = 1;
private double userScale = 1.5; private double userScale = .5;
public ImagePanel () public ImagePanel ()
{ {
this.setBackground (new Color (BACKGROUND, BACKGROUND, BACKGROUND)); this.setBackground (new Color (BACKGROUND, BACKGROUND, BACKGROUND));
} }
private void setScale (double scale)
{
this.userScale = scale;
}
private void setImage (BufferedImage image) private void setImage (BufferedImage image)
{ {
this.image = image; this.image = image;

View File

@ -118,6 +118,10 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
duplicateAction.addTableSelectionListener (catalogPanel); duplicateAction.addTableSelectionListener (catalogPanel);
menuHandler.scale1Item.setAction (new ScaleAction (dataPanel, 1.0, 1));
menuHandler.scale2Item.setAction (new ScaleAction (dataPanel, 1.5, 2));
menuHandler.scale3Item.setAction (new ScaleAction (dataPanel, 2.0, 3));
redoHandler.addRedoListener (catalogPanel); redoHandler.addRedoListener (catalogPanel);
redoHandler.addRedoListener (diskLayoutPanel); redoHandler.addRedoListener (diskLayoutPanel);

View File

@ -454,15 +454,12 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
switch (prefs.getInt (PREFS_SCALE, 2)) switch (prefs.getInt (PREFS_SCALE, 2))
{ {
case 1: case 1:
scale1Item.setSelected (true);
scale1Item.doClick (); scale1Item.doClick ();
break; break;
case 2: case 2:
scale2Item.setSelected (true);
scale2Item.doClick (); scale2Item.doClick ();
break; break;
case 3: case 3:
scale3Item.setSelected (true);
scale3Item.doClick (); scale3Item.doClick ();
break; break;
} }

View File

@ -0,0 +1,39 @@
package com.bytezone.diskbrowser.gui;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.KeyStroke;
public class ScaleAction extends AbstractAction
{
private final DataPanel owner;
private double scale;
// ---------------------------------------------------------------------------------//
public ScaleAction (DataPanel owner, double scale, int menu)
// ---------------------------------------------------------------------------------//
{
super ("Scale " + scale);
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
putValue (Action.SHORT_DESCRIPTION, "Scale image");
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (
(menu == 1 ? KeyEvent.VK_1 : menu == 2 ? KeyEvent.VK_2 : KeyEvent.VK_3), mask));
this.owner = owner;
this.scale = scale;
}
// ---------------------------------------------------------------------------------//
@Override
public void actionPerformed (ActionEvent e)
// ---------------------------------------------------------------------------------//
{
owner.setScale (scale);
}
}