diff --git a/src/com/bytezone/diskbrowser/applefile/DebugBasicFormatter.java b/src/com/bytezone/diskbrowser/applefile/DebugBasicFormatter.java index 5a41c94..196de2f 100644 --- a/src/com/bytezone/diskbrowser/applefile/DebugBasicFormatter.java +++ b/src/com/bytezone/diskbrowser/applefile/DebugBasicFormatter.java @@ -86,8 +86,6 @@ public class DebugBasicFormatter extends BasicFormatter text.append (assemblerProgram.getText ()); } } - - // return Utility.rtrim (text); } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/applefile/FontFile.java b/src/com/bytezone/diskbrowser/applefile/FontFile.java index 5e29d9d..74b738b 100644 --- a/src/com/bytezone/diskbrowser/applefile/FontFile.java +++ b/src/com/bytezone/diskbrowser/applefile/FontFile.java @@ -32,9 +32,11 @@ public class FontFile extends CharacterList { if (buffer.length % 8 != 0) return false; + for (int i = 0; i < 8; i++) if (buffer[i] != 0 && buffer[i] != 0x7F) return false; + return true; } diff --git a/src/com/bytezone/diskbrowser/applefile/HiResImage.java b/src/com/bytezone/diskbrowser/applefile/HiResImage.java index 6ecb285..94f5011 100644 --- a/src/com/bytezone/diskbrowser/applefile/HiResImage.java +++ b/src/com/bytezone/diskbrowser/applefile/HiResImage.java @@ -301,23 +301,13 @@ public abstract class HiResImage extends AbstractFile break; case ProdosConstants.FILE_TYPE_PIC: // 0xC1 - switch (auxType) + auxText = switch (auxType) { - case 0: - case 0x2000: - case 0x0042: - case 0x0043: - auxText = "Super Hi-res Screen Image"; - break; - case 1: - auxText = "QuickDraw PICT File"; - break; - case 2: - auxText = "Super Hi-Res 3200 color image"; - break; - default: - auxText = "Unknown aux: " + auxType; - } + case 0, 0x2000, 0x0042, 0x0043 -> "Super Hi-res Screen Image"; + case 1 -> "QuickDraw PICT File"; + case 2 -> "Super Hi-Res 3200 color image"; + default -> "Unknown aux: " + auxType; + }; } if (!auxText.isEmpty ()) diff --git a/src/com/bytezone/diskbrowser/applefile/MagicWindowText.java b/src/com/bytezone/diskbrowser/applefile/MagicWindowText.java index b03f178..8cbf286 100644 --- a/src/com/bytezone/diskbrowser/applefile/MagicWindowText.java +++ b/src/com/bytezone/diskbrowser/applefile/MagicWindowText.java @@ -12,6 +12,7 @@ public class MagicWindowText extends AbstractFile super (name, buffer); } + // this was copied from SimpleText, should probably combine them // ---------------------------------------------------------------------------------// @Override public String getText () diff --git a/src/com/bytezone/diskbrowser/applefile/PascalInfo.java b/src/com/bytezone/diskbrowser/applefile/PascalInfo.java index 78f1d17..039a447 100644 --- a/src/com/bytezone/diskbrowser/applefile/PascalInfo.java +++ b/src/com/bytezone/diskbrowser/applefile/PascalInfo.java @@ -4,6 +4,8 @@ package com.bytezone.diskbrowser.applefile; public class PascalInfo extends AbstractFile // -----------------------------------------------------------------------------------// { + private static final byte CR = 0x0D; + // ---------------------------------------------------------------------------------// public PascalInfo (String name, byte[] buffer) // ---------------------------------------------------------------------------------// @@ -19,10 +21,7 @@ public class PascalInfo extends AbstractFile StringBuilder text = new StringBuilder (getHeader ()); for (int i = 0; i < buffer.length; i++) - if (buffer[i] == 0x0D) - text.append ("\n"); - else - text.append ((char) buffer[i]); + text.append (buffer[i] == CR ? "\n" : (char) buffer[i]); return text.toString (); } diff --git a/src/com/bytezone/diskbrowser/applefile/Selector.java b/src/com/bytezone/diskbrowser/applefile/Selector.java index 59f800c..226e588 100644 --- a/src/com/bytezone/diskbrowser/applefile/Selector.java +++ b/src/com/bytezone/diskbrowser/applefile/Selector.java @@ -77,21 +77,14 @@ public class Selector extends AbstractFile labelLength = buffer[ptr] & 0xFF; label = new String (buffer, ptr + 1, labelLength); copyFlags = buffer[ptr + 15]; - switch (copyFlags & 0xFF) + + copyText = switch (copyFlags & 0xFF) { - case 0: - copyText = "First boot"; - break; - case 0x80: - copyText = "First use"; - break; - case 0xC0: - copyText = "Never"; - break; - default: - copyText = "Unknown"; - break; - } + case 0x00 -> "First boot"; + case 0x80 -> "First use"; + case 0xC0 -> "Never"; + default -> "Unknown"; + }; } } diff --git a/src/com/bytezone/diskbrowser/applefile/Shape.java b/src/com/bytezone/diskbrowser/applefile/Shape.java new file mode 100644 index 0000000..10debb1 --- /dev/null +++ b/src/com/bytezone/diskbrowser/applefile/Shape.java @@ -0,0 +1,235 @@ +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.utilities.HexFormatter; +import com.bytezone.diskbrowser.utilities.Utility; + +// -----------------------------------------------------------------------------------// +class Shape +// -----------------------------------------------------------------------------------// +{ + private static final int SIZE = 400; + + private final byte[] buffer; + private final int index; + + int offset; + int actualLength; + int minRow, maxRow; + int minCol, maxCol; + int startRow = SIZE / 2; + int startCol = SIZE / 2; + int[][] grid = new int[SIZE][SIZE]; + int[][] displayGrid; + boolean valid; + + BufferedImage image; + + // ---------------------------------------------------------------------------------// + public Shape (byte[] buffer, int index) + // ---------------------------------------------------------------------------------// + { + this.index = index; + this.buffer = buffer; + + int row = startRow; + int col = startCol; + + offset = Utility.unsignedShort (buffer, index * 2 + 2); + + int ptr = offset; + while (ptr < buffer.length) + { + int value = buffer[ptr++] & 0xFF; + + if (value == 0) + break; + + // P = plot + // DD = direction to move + int v1 = value >>> 6; // DD...... + int v2 = (value & 0x38) >>> 3; // ..PDD... + int v3 = value & 0x07; // .....PDD + + // rightmost 3 bits + if (v3 >= 4) + if (!plot (grid, row, col)) + return; + + if (v3 == 0 || v3 == 4) + row--; + else if (v3 == 1 || v3 == 5) + col++; + else if (v3 == 2 || v3 == 6) + row++; + else + col--; + + // middle 3 bits + if (v2 >= 4) + if (!plot (grid, row, col)) + return; + + // cannot move up without plotting if v1 is zero + if ((v2 == 0 && v1 != 0) || v2 == 4) + row--; + else if (v2 == 1 || v2 == 5) + col++; + else if (v2 == 2 || v2 == 6) + row++; + else if (v2 == 3 || v2 == 7) + col--; + + // leftmost 2 bits (cannot plot or move up) + if (v1 == 1) + col++; + else if (v1 == 2) + row++; + else if (v1 == 3) + col--; + } + + actualLength = ptr - offset; + + // endRow = row; + // endCol = col; + + // find min and max rows with pixels + minRow = startRow; + maxRow = startRow; + // minRow = Math.min (minRow, endRow); + // maxRow = Math.max (maxRow, endRow); + for (row = 1; row < grid.length; row++) + { + if (grid[row][0] > 0) + { + minRow = Math.min (minRow, row); + maxRow = Math.max (maxRow, row); + } + } + + // find min and max columns with pixels + minCol = startCol; + maxCol = startCol; + // minCol = Math.min (minCol, endCol); + // maxCol = Math.max (maxCol, endCol); + for (col = 1; col < grid[0].length; col++) + { + if (grid[0][col] > 0) + { + minCol = Math.min (minCol, col); + maxCol = Math.max (maxCol, col); + } + } + valid = true; + } + + // ---------------------------------------------------------------------------------// + void convertGrid (int offsetRows, int offsetColumns, int rows, int columns) + // ---------------------------------------------------------------------------------// + { + // System.out.printf ("Converting shape # %d%n", index); + // System.out.printf ("offsetRows %d offsetCols %d%n", offsetRows, + // offsetColumns); + // System.out.printf ("rows %d cols %d%n", rows, columns); + + displayGrid = new int[rows][columns]; + for (int row = 0; row < rows; row++) + for (int col = 0; col < columns; col++) + displayGrid[row][col] = grid[offsetRows + row][offsetColumns + col]; + grid = null; + + // draw the image + image = new BufferedImage (columns, rows, BufferedImage.TYPE_BYTE_GRAY); + DataBuffer dataBuffer = image.getRaster ().getDataBuffer (); + int element = 0; + for (int row = 0; row < rows; row++) + for (int col = 0; col < columns; col++) + dataBuffer.setElem (element++, displayGrid[row][col] == 0 ? 0 : 255); + + startRow -= offsetRows; + startCol -= offsetColumns; + // endRow -= offsetRows; + // endCol -= offsetColumns; + } + + // ---------------------------------------------------------------------------------// + private boolean plot (int[][] grid, int row, int col) + // ---------------------------------------------------------------------------------// + { + if (row < 0 || row >= SIZE || col < 0 || col >= SIZE) + { + System.out.printf ("Shape table out of range: %d, %d%n", row, col); + return false; + } + grid[row][col] = 1; // plot + grid[0][col]++; // increment total column dots + grid[row][0]++; // increment total row dots + + return true; + } + + // ---------------------------------------------------------------------------------// + public void drawText (StringBuilder text) + // ---------------------------------------------------------------------------------// + { + text.append (String.format ("Shape : %d%n", index)); + text.append (String.format ("Size : %d%n", actualLength)); + // text.append (String.format ("Width : %d%n", width)); + // text.append (String.format ("Height : %d%n", height)); + + // append the shape's data + String bytes = HexFormatter.getHexString (buffer, offset, actualLength); + int ptr = offset; + for (String s : split (bytes)) + { + text.append (String.format (" %04X : %s%n", ptr, s)); + ptr += 16; + } + text.append ("\n"); + + for (int row = 0; row < displayGrid.length; row++) + { + for (int col = 0; col < displayGrid[0].length; col++) + if (col == startCol && row == startRow) + text.append (displayGrid[row][col] > 0 ? " @" : " ."); + // else if (col == endCol && row == endRow) + // text.append (displayGrid[row][col] > 0 ? " #" : " ."); + else if (displayGrid[row][col] == 0) + text.append (" "); + else + text.append (" X"); + + text.append ("\n"); + } + + text.append ("\n"); + } + + // ---------------------------------------------------------------------------------// + private List split (String line) + // ---------------------------------------------------------------------------------// + { + List list = new ArrayList<> (); + while (line.length () > 48) + { + list.add (line.substring (0, 47)); + line = line.substring (48); + } + list.add (line); + return list; + } + + // ---------------------------------------------------------------------------------// + @Override + public String toString () + // ---------------------------------------------------------------------------------// + { + return String.format ("%3d %3d %3d %3d %3d", index, minRow, maxRow, minCol, + maxCol); + } +} diff --git a/src/com/bytezone/diskbrowser/applefile/ShapeTable.java b/src/com/bytezone/diskbrowser/applefile/ShapeTable.java index 468408a..56e407d 100755 --- a/src/com/bytezone/diskbrowser/applefile/ShapeTable.java +++ b/src/com/bytezone/diskbrowser/applefile/ShapeTable.java @@ -3,11 +3,9 @@ package com.bytezone.diskbrowser.applefile; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; import java.util.ArrayList; import java.util.List; -import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.Utility; /*- @@ -27,7 +25,6 @@ public class ShapeTable extends AbstractFile // -----------------------------------------------------------------------------------// { private final List shapes = new ArrayList<> (); - private static final int SIZE = 400; int maxWidth = 0; int maxHeight = 0; @@ -142,216 +139,4 @@ public class ShapeTable extends AbstractFile return true; } - - // ---------------------------------------------------------------------------------// - class Shape - // ---------------------------------------------------------------------------------// - { - private final byte[] buffer; - private final int index; - - int offset; - int actualLength; - int minRow, maxRow; - int minCol, maxCol; - int startRow = SIZE / 2; - int startCol = SIZE / 2; - int[][] grid = new int[SIZE][SIZE]; - int[][] displayGrid; - boolean valid; - - private BufferedImage image; - - public Shape (byte[] buffer, int index) - { - this.index = index; - this.buffer = buffer; - - int row = startRow; - int col = startCol; - - offset = Utility.unsignedShort (buffer, index * 2 + 2); - - int ptr = offset; - while (ptr < buffer.length) - { - int value = buffer[ptr++] & 0xFF; - - if (value == 0) - break; - - // P = plot - // DD = direction to move - int v1 = value >>> 6; // DD...... - int v2 = (value & 0x38) >>> 3; // ..PDD... - int v3 = value & 0x07; // .....PDD - - // rightmost 3 bits - if (v3 >= 4) - if (!plot (grid, row, col)) - return; - - if (v3 == 0 || v3 == 4) - row--; - else if (v3 == 1 || v3 == 5) - col++; - else if (v3 == 2 || v3 == 6) - row++; - else - col--; - - // middle 3 bits - if (v2 >= 4) - if (!plot (grid, row, col)) - return; - - // cannot move up without plotting if v1 is zero - if ((v2 == 0 && v1 != 0) || v2 == 4) - row--; - else if (v2 == 1 || v2 == 5) - col++; - else if (v2 == 2 || v2 == 6) - row++; - else if (v2 == 3 || v2 == 7) - col--; - - // leftmost 2 bits (cannot plot or move up) - if (v1 == 1) - col++; - else if (v1 == 2) - row++; - else if (v1 == 3) - col--; - } - - actualLength = ptr - offset; - - // endRow = row; - // endCol = col; - - // find min and max rows with pixels - minRow = startRow; - maxRow = startRow; - // minRow = Math.min (minRow, endRow); - // maxRow = Math.max (maxRow, endRow); - for (row = 1; row < grid.length; row++) - { - if (grid[row][0] > 0) - { - minRow = Math.min (minRow, row); - maxRow = Math.max (maxRow, row); - } - } - - // find min and max columns with pixels - minCol = startCol; - maxCol = startCol; - // minCol = Math.min (minCol, endCol); - // maxCol = Math.max (maxCol, endCol); - for (col = 1; col < grid[0].length; col++) - { - if (grid[0][col] > 0) - { - minCol = Math.min (minCol, col); - maxCol = Math.max (maxCol, col); - } - } - valid = true; - } - - void convertGrid (int offsetRows, int offsetColumns, int rows, int columns) - { - // System.out.printf ("Converting shape # %d%n", index); - // System.out.printf ("offsetRows %d offsetCols %d%n", offsetRows, - // offsetColumns); - // System.out.printf ("rows %d cols %d%n", rows, columns); - - displayGrid = new int[rows][columns]; - for (int row = 0; row < rows; row++) - for (int col = 0; col < columns; col++) - displayGrid[row][col] = grid[offsetRows + row][offsetColumns + col]; - grid = null; - - // draw the image - image = new BufferedImage (columns, rows, BufferedImage.TYPE_BYTE_GRAY); - DataBuffer dataBuffer = image.getRaster ().getDataBuffer (); - int element = 0; - for (int row = 0; row < rows; row++) - for (int col = 0; col < columns; col++) - dataBuffer.setElem (element++, displayGrid[row][col] == 0 ? 0 : 255); - - startRow -= offsetRows; - startCol -= offsetColumns; - // endRow -= offsetRows; - // endCol -= offsetColumns; - } - - private boolean plot (int[][] grid, int row, int col) - { - if (row < 0 || row >= SIZE || col < 0 || col >= SIZE) - { - System.out.printf ("Shape table out of range: %d, %d%n", row, col); - return false; - } - grid[row][col] = 1; // plot - grid[0][col]++; // increment total column dots - grid[row][0]++; // increment total row dots - - return true; - } - - public void drawText (StringBuilder text) - { - text.append (String.format ("Shape : %d%n", index)); - text.append (String.format ("Size : %d%n", actualLength)); - // text.append (String.format ("Width : %d%n", width)); - // text.append (String.format ("Height : %d%n", height)); - - // append the shape's data - String bytes = HexFormatter.getHexString (buffer, offset, actualLength); - int ptr = offset; - for (String s : split (bytes)) - { - text.append (String.format (" %04X : %s%n", ptr, s)); - ptr += 16; - } - text.append ("\n"); - - for (int row = 0; row < displayGrid.length; row++) - { - for (int col = 0; col < displayGrid[0].length; col++) - if (col == startCol && row == startRow) - text.append (displayGrid[row][col] > 0 ? " @" : " ."); - // else if (col == endCol && row == endRow) - // text.append (displayGrid[row][col] > 0 ? " #" : " ."); - else if (displayGrid[row][col] == 0) - text.append (" "); - else - text.append (" X"); - - text.append ("\n"); - } - - text.append ("\n"); - } - - private List split (String line) - { - List list = new ArrayList<> (); - while (line.length () > 48) - { - list.add (line.substring (0, 47)); - line = line.substring (48); - } - list.add (line); - return list; - } - - @Override - public String toString () - { - return String.format ("%3d %3d %3d %3d %3d", index, minRow, maxRow, minCol, - maxCol); - } - } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java b/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java index 072181e..dfb6ac0 100644 --- a/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java +++ b/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java @@ -1,5 +1,14 @@ package com.bytezone.diskbrowser.dos; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.AA; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.ApplesoftBasic; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.BB; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.Binary; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.IntegerBasic; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.Relocatable; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.SS; +import static com.bytezone.diskbrowser.dos.DosDisk.FileType.Text; + import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -63,34 +72,25 @@ abstract class AbstractCatalogEntry implements AppleFileSource int type = entryBuffer[2] & 0x7F; locked = (entryBuffer[2] & 0x80) != 0; - if (type == 0) - fileType = FileType.Text; - else if ((type == 0x01)) - fileType = FileType.IntegerBasic; - else if ((type == 0x02)) - fileType = FileType.ApplesoftBasic; - else if ((type < 0x08)) - fileType = FileType.Binary; - else if ((type < 0x10)) - fileType = FileType.SS; - else if ((type < 0x20)) - fileType = FileType.Relocatable; - else if ((type < 0x40)) - fileType = FileType.AA; - // else if ((type == 0x40)) // Lisa - else - fileType = FileType.Binary; - // else - // { - // System.out.println ("Unknown file type : " + type); - // } + fileType = switch (type) + { + case 0x00 -> Text; + case 0x01 -> IntegerBasic; + case 0x02 -> ApplesoftBasic; + case 0x04 -> Binary; + case 0x08 -> SS; + case 0x10 -> Relocatable; + case 0x20 -> AA; + case 0x40 -> BB; + default -> Binary; // should never happen + }; if (dosDisk.getVersion () >= 0x41) lastModified = Utility.getDateTime (entryBuffer, 0x1B); // CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6 - String base = String.format ("%s%s %03d ", (locked) ? "*" : " ", getFileType (), - reportedSize % 1000); + String base = String.format ("%s%s %03d ", locked ? "*" : " ", getFileType (), + reportedSize & 0xFF); catalogName = getName (base, entryBuffer); displayName = getDisplayName (entryBuffer); } diff --git a/src/com/bytezone/diskbrowser/dos/DosDisk.java b/src/com/bytezone/diskbrowser/dos/DosDisk.java index cd6dc62..f930094 100755 --- a/src/com/bytezone/diskbrowser/dos/DosDisk.java +++ b/src/com/bytezone/diskbrowser/dos/DosDisk.java @@ -46,7 +46,7 @@ public class DosDisk extends AbstractFormattedDisk enum FileType { - Text, ApplesoftBasic, IntegerBasic, Binary, Relocatable, SS, AA, BB + Text, ApplesoftBasic, IntegerBasic, Binary, SS, Relocatable, AA, BB } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/prodos/FileEntry.java b/src/com/bytezone/diskbrowser/prodos/FileEntry.java index 0c721f0..f05260e 100755 --- a/src/com/bytezone/diskbrowser/prodos/FileEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/FileEntry.java @@ -289,7 +289,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants file = new Selector (name, exactBuffer); break; } - // drop through + + // drop through !! + case FILE_TYPE_BINARY: case FILE_TYPE_RELOCATABLE: case FILE_TYPE_SYS: diff --git a/src/com/bytezone/diskbrowser/utilities/LZW.java b/src/com/bytezone/diskbrowser/utilities/LZW.java index d1df7d8..4ca0cbf 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW.java @@ -125,7 +125,7 @@ class LZW } // ---------------------------------------------------------------------------------// - protected int width (int maximumValue) + int width (int maximumValue) // ---------------------------------------------------------------------------------// { return 32 - Integer.numberOfLeadingZeros (maximumValue);