mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2025-01-18 03:30:18 +00:00
more graphics
This commit is contained in:
parent
c09ddea735
commit
462744dce1
49
src/com/bytezone/diskbrowser/applefile/FaddenHiResImage.java
Normal file
49
src/com/bytezone/diskbrowser/applefile/FaddenHiResImage.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
public class FaddenHiResImage extends OriginalHiResImage
|
||||
{
|
||||
// https://github.com/fadden/fhpack/blob/master/fhpack.cpp
|
||||
|
||||
public FaddenHiResImage (String name, byte[] buffer, int fileType, int auxType,
|
||||
int endOfFile)
|
||||
{
|
||||
super (name, buffer, fileType, auxType, endOfFile);
|
||||
|
||||
assert buffer[0] == 0x66;
|
||||
|
||||
this.buffer = new byte[0x2000];
|
||||
int outPtr = 0;
|
||||
|
||||
int ptr = 1;
|
||||
while (ptr < buffer.length)
|
||||
{
|
||||
int literalLen = (buffer[ptr] & 0xF0) >>> 4;
|
||||
int matchLen = (buffer[ptr++] & 0x0F) + 4;
|
||||
|
||||
if (literalLen == 15)
|
||||
literalLen = (buffer[ptr++] & 0xFF) + 15;
|
||||
|
||||
if (literalLen > 0)
|
||||
{
|
||||
System.arraycopy (buffer, ptr, this.buffer, outPtr, literalLen);
|
||||
ptr += literalLen;
|
||||
outPtr += literalLen;
|
||||
}
|
||||
|
||||
if (matchLen == 19) // 15 + 4
|
||||
{
|
||||
matchLen = (buffer[ptr++] & 0xFF);
|
||||
if (matchLen == 254) // eof
|
||||
break;
|
||||
if (matchLen == 253) // no match
|
||||
continue;
|
||||
matchLen += 19;
|
||||
}
|
||||
|
||||
int offset = (buffer[ptr++] & 0xFF) | ((buffer[ptr++] & 0xFF) << 8);
|
||||
while (matchLen-- > 0)
|
||||
this.buffer[outPtr++] = this.buffer[offset++];
|
||||
}
|
||||
createImage ();
|
||||
}
|
||||
}
|
@ -26,9 +26,10 @@ public abstract class HiResImage extends AbstractFile
|
||||
// $06 BIN .3200 - SHRPictureFile2
|
||||
// $06 BIN .3201 - SHRPictureFile2
|
||||
|
||||
// $08 PICT <$4000 Apple II Graphics File - ???
|
||||
// $08 PICT $4000 Packed Hi-Res file - ???
|
||||
// $08 PICT $4001 Packed Double Hi-Res file - ???
|
||||
// $08 FOT <$4000 Apple II Graphics File - ???
|
||||
// $08 FOT $4000 Packed Hi-Res file - ???
|
||||
// $08 FOT $4001 Packed Double Hi-Res file - ???
|
||||
// $08 FOT $8066 Fadden Hi-res
|
||||
|
||||
// * $C0 PNT $0000 Paintworks Packed Super Hi-Res - SHRPictureFile2
|
||||
// * $C0 PNT $0001 Packed IIGS Super Hi-Res Image - SHRPictureFile2
|
||||
@ -153,6 +154,13 @@ public abstract class HiResImage extends AbstractFile
|
||||
}
|
||||
|
||||
/*-
|
||||
* Files of type $08 and any auxiliary type less than or equal to $3FFF contain a
|
||||
* standard Apple II graphics file in one of several modes. After determining that
|
||||
* the auxiliary type is not $4000 or $4001 (which have been defined for high-resolution
|
||||
* and double high-resolution pictures packed with the Apple IIGS PackBytes routine),
|
||||
* you can determine the mode of the file by examining byte +120 (+$78). The value of
|
||||
* this byte, which ranges from zero to seven, is interpreted as follows:
|
||||
*
|
||||
Mode Page 1 Page 2
|
||||
280 x 192 Black & White 0 4
|
||||
280 x 192 Limited Color 1 5
|
||||
@ -172,7 +180,7 @@ public abstract class HiResImage extends AbstractFile
|
||||
|
||||
switch (fileType)
|
||||
{
|
||||
case ProdosConstants.FILE_TYPE_PICT: // 0x08
|
||||
case ProdosConstants.FILE_TYPE_FOT: // 0x08
|
||||
if (auxType < 0x4000)
|
||||
{
|
||||
auxText = "Apple II Graphics File";
|
||||
@ -183,6 +191,8 @@ public abstract class HiResImage extends AbstractFile
|
||||
auxText = "Packed Hi-Res File";
|
||||
else if (auxType == 0x4001)
|
||||
auxText = "Packed Double Hi-Res File";
|
||||
else if (auxType == 0x8066)
|
||||
auxText = "Fadden Hi-Res File";
|
||||
else
|
||||
auxText = "Unknown aux: " + auxType;
|
||||
break;
|
||||
|
@ -34,7 +34,7 @@ public class OriginalHiResImage extends HiResImage
|
||||
{
|
||||
super (name, buffer, fileType, auxType, eof);
|
||||
|
||||
// createImage ();
|
||||
// will call createImage () itself
|
||||
}
|
||||
|
||||
// https://github.com/Michaelangel007/apple2_hgr_font_tutorial
|
||||
|
@ -21,8 +21,8 @@ class MC3470
|
||||
private boolean restarted;
|
||||
|
||||
private DiskReader diskReader;
|
||||
private final DiskReader diskReader16 = new DiskReader16Sector ();
|
||||
private final DiskReader diskReader13 = new DiskReader13Sector ();
|
||||
private final DiskReader diskReader16Sector = new DiskReader16Sector ();
|
||||
private final DiskReader diskReader13Sector = new DiskReader13Sector ();
|
||||
|
||||
private final byte[] dataBuffer = new byte[MAX_DATA];
|
||||
private int dataPtr = 0;
|
||||
@ -39,7 +39,6 @@ class MC3470
|
||||
List<RawDiskSector> readTrack (byte[] buffer, int offset, int bytesUsed, int bitCount)
|
||||
throws DiskNibbleException
|
||||
{
|
||||
final int max = offset + bytesUsed;
|
||||
int totalBits = 0;
|
||||
int totalBytes = 0;
|
||||
|
||||
@ -47,21 +46,16 @@ class MC3470
|
||||
diskReader = null;
|
||||
currentDiskSector = null;
|
||||
currentState = State.OTHER;
|
||||
finished = false;
|
||||
restarted = false;
|
||||
|
||||
byte value = 0; // value to be stored
|
||||
dataPtr = 0;
|
||||
expectedDataSize = MAX_DATA;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
System.out.printf ("%nOffset : %06X%n", offset);
|
||||
System.out.printf ("Bytes used: %06X%n", bytesUsed);
|
||||
System.out.printf ("Bit count : %06X%n", bitCount);
|
||||
}
|
||||
int inPtr = offset; // keep offset in case we have to loop around
|
||||
final int max = offset + bytesUsed;
|
||||
finished = false;
|
||||
|
||||
int inPtr = offset; // keep offset in case we have to loop around
|
||||
while (inPtr < max && !finished)
|
||||
{
|
||||
byte b = buffer[inPtr++];
|
||||
@ -84,16 +78,23 @@ class MC3470
|
||||
System.out.printf ("%02X ", value);
|
||||
}
|
||||
|
||||
if (dataPtr >= MAX_DATA)
|
||||
throw new DiskNibbleException ("No prologues found");
|
||||
|
||||
dataBuffer[dataPtr++] = value;
|
||||
checkState (value);
|
||||
value = 0;
|
||||
|
||||
if (currentState == State.OTHER)
|
||||
checkState ();
|
||||
else if (dataPtr == expectedDataSize) // DATA or ADDRESS is now complete
|
||||
setState (State.OTHER);
|
||||
}
|
||||
|
||||
if (++totalBits == bitCount)
|
||||
if (++totalBits == bitCount) // only use this many bits
|
||||
break;
|
||||
}
|
||||
|
||||
// check for unfinished data block, we may need to restart the track
|
||||
// check for unfinished data block, we may need to restart from the beginning
|
||||
if (inPtr == max && currentState == State.DATA && !restarted)
|
||||
{
|
||||
inPtr = offset;
|
||||
@ -114,6 +115,146 @@ class MC3470
|
||||
return diskSectors;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// checkState
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void checkState () throws DiskNibbleException
|
||||
{
|
||||
assert currentState == State.OTHER;
|
||||
|
||||
switch (dataBuffer[dataPtr - 1]) // last byte added
|
||||
{
|
||||
case (byte) 0xB5:
|
||||
if (isPrologue ())
|
||||
{
|
||||
diskReader = diskReader13Sector;
|
||||
setState (State.ADDRESS);
|
||||
}
|
||||
break;
|
||||
|
||||
case (byte) 0x96:
|
||||
if (isPrologue ())
|
||||
{
|
||||
diskReader = diskReader16Sector;
|
||||
setState (State.ADDRESS);
|
||||
}
|
||||
break;
|
||||
|
||||
case (byte) 0xAD:
|
||||
if (isPrologue ())
|
||||
setState (State.DATA);
|
||||
break;
|
||||
|
||||
case (byte) 0xEB:
|
||||
if (isEpilogue ())
|
||||
setState (State.OTHER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// setState
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void setState (State newState) throws DiskNibbleException
|
||||
{
|
||||
if (currentState == State.OTHER && newState == State.OTHER)
|
||||
return;
|
||||
|
||||
assert currentState != newState : currentState + " -> " + newState;
|
||||
|
||||
switch (currentState) // this state is now finished
|
||||
{
|
||||
case ADDRESS:
|
||||
if (currentDiskSector != null)
|
||||
throw new DiskNibbleException ("unused ADDRESS: " + currentDiskSector);
|
||||
|
||||
currentDiskSector = new RawDiskSector (new DiskAddressField (dataBuffer));
|
||||
if (dump)
|
||||
System.out.println ("\n" + currentDiskSector);
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
if (currentDiskSector == null)
|
||||
throw new DiskNibbleException ("cannot store DATA without ADDRESS");
|
||||
|
||||
currentDiskSector.setBuffer (diskReader.decodeSector (dataBuffer));
|
||||
diskSectors.add (currentDiskSector);
|
||||
currentDiskSector = null;
|
||||
if (diskSectors.size () == diskReader.sectorsPerTrack)
|
||||
finished = true;
|
||||
|
||||
break;
|
||||
|
||||
case OTHER: // triggered by an epilogue or full address/data buffer
|
||||
break;
|
||||
}
|
||||
|
||||
switch (newState) // this state is now starting
|
||||
{
|
||||
case ADDRESS:
|
||||
expectedDataSize = 8;
|
||||
if (dump)
|
||||
System.out.print ("ADDRESS ");
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
expectedDataSize = diskReader.expectedDataSize ();
|
||||
if (dump)
|
||||
System.out.println ("DATA");
|
||||
if (debug && currentDiskSector == null)
|
||||
{
|
||||
System.out.println ("starting DATA with no ADDRESS");
|
||||
System.out.println (HexFormatter.format (dataBuffer, 0, dataPtr));
|
||||
}
|
||||
break;
|
||||
|
||||
case OTHER:
|
||||
expectedDataSize = MAX_DATA; // what is the maximum filler?
|
||||
if (dump)
|
||||
System.out.println ("OTHER");
|
||||
break;
|
||||
}
|
||||
|
||||
currentState = newState;
|
||||
dataPtr = 0; // start collecting new buffer
|
||||
}
|
||||
|
||||
// D5 AA 96 16 sector address prologue
|
||||
// D5 AA B5 13 sector address prologue
|
||||
// D5 AA AD data prologue
|
||||
// DE AA EB epilogue
|
||||
|
||||
// non-standard:
|
||||
// D4 AA 96 xx sector address prologue - Bouncing Kamungas
|
||||
// D5 BB CF data prologue - Hard Hat Mac
|
||||
// DA AA EB address epilogue - Bouncing Kamungas
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// isPrologue
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private boolean isPrologue ()
|
||||
{
|
||||
return dataPtr >= 3
|
||||
&& (dataBuffer[dataPtr - 3] == (byte) 0xD5
|
||||
|| dataBuffer[dataPtr - 3] == (byte) 0xD4) // non-standard
|
||||
&& dataBuffer[dataPtr - 2] == (byte) 0xAA;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// isEpilogue
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private boolean isEpilogue ()
|
||||
{
|
||||
return dataPtr >= 3
|
||||
&& (dataBuffer[dataPtr - 3] == (byte) 0xDE
|
||||
|| dataBuffer[dataPtr - 3] == (byte) 0xDA) // non-standard
|
||||
&& dataBuffer[dataPtr - 2] == (byte) 0xAA;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// storeSectors
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@ -145,143 +286,4 @@ class MC3470
|
||||
{
|
||||
return diskSectors.size () == 16 && diskReader.sectorsPerTrack == 16;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// checkState
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void checkState (byte value) throws DiskNibbleException
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case (byte) 0xB5:
|
||||
if (isPrologue ())
|
||||
{
|
||||
diskReader = diskReader13;
|
||||
setState (State.ADDRESS);
|
||||
}
|
||||
break;
|
||||
|
||||
case (byte) 0x96:
|
||||
if (isPrologue ())
|
||||
{
|
||||
diskReader = diskReader16;
|
||||
setState (State.ADDRESS);
|
||||
}
|
||||
break;
|
||||
|
||||
case (byte) 0xAD:
|
||||
if (isPrologue ())
|
||||
setState (State.DATA);
|
||||
break;
|
||||
|
||||
case (byte) 0xEB:
|
||||
if (isEpilogue ())
|
||||
setState (State.OTHER);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dataPtr == expectedDataSize)
|
||||
{
|
||||
if (currentState == State.OTHER)
|
||||
throw new DiskNibbleException ("No address or data blocks found");
|
||||
setState (State.OTHER);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// setState
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void setState (State newState) throws DiskNibbleException
|
||||
{
|
||||
if (currentState == newState && currentState == State.OTHER)
|
||||
return;
|
||||
assert currentState != newState : currentState + " -> " + newState;
|
||||
|
||||
switch (currentState) // this state is now finished
|
||||
{
|
||||
case ADDRESS:
|
||||
if (currentDiskSector != null)
|
||||
System.out.printf ("unused ADDRESS: %s%n", currentDiskSector);
|
||||
|
||||
currentDiskSector = new RawDiskSector (new DiskAddressField (dataBuffer));
|
||||
if (dump)
|
||||
System.out.println (currentDiskSector);
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
if (currentDiskSector == null)
|
||||
{
|
||||
System.out.printf ("cannot store %d DATA no ADDRESS", dataPtr);
|
||||
if (debug)
|
||||
System.out.println (HexFormatter.format (dataBuffer, 0, dataPtr));
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDiskSector.setBuffer (diskReader.decodeSector (dataBuffer));
|
||||
diskSectors.add (currentDiskSector);
|
||||
currentDiskSector = null;
|
||||
if (diskSectors.size () == diskReader.sectorsPerTrack)
|
||||
finished = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case OTHER: // triggered by an epilogue or full address/data buffer
|
||||
break;
|
||||
}
|
||||
|
||||
switch (newState) // this state is now starting
|
||||
{
|
||||
case ADDRESS:
|
||||
if (dump)
|
||||
System.out.print ("ADDRESS ");
|
||||
expectedDataSize = 8;
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
if (dump)
|
||||
System.out.println ("DATA");
|
||||
if (debug && currentDiskSector == null)
|
||||
{
|
||||
System.out.println ("starting DATA with no ADDRESS");
|
||||
System.out.println (HexFormatter.format (dataBuffer, 0, dataPtr));
|
||||
}
|
||||
expectedDataSize = diskReader.expectedDataSize ();
|
||||
break;
|
||||
|
||||
case OTHER:
|
||||
if (dump)
|
||||
System.out.println ("OTHER");
|
||||
expectedDataSize = MAX_DATA; // what is the maximum filler?
|
||||
break;
|
||||
}
|
||||
|
||||
currentState = newState;
|
||||
dataPtr = 0; // start collecting new buffer
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// isPrologue
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private boolean isPrologue ()
|
||||
{
|
||||
return dataPtr >= 3
|
||||
&& (dataBuffer[dataPtr - 3] == (byte) 0xD5
|
||||
|| dataBuffer[dataPtr - 3] == (byte) 0xD4) // non-standard
|
||||
&& dataBuffer[dataPtr - 2] == (byte) 0xAA;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// isEpilogue
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private boolean isEpilogue ()
|
||||
{
|
||||
return dataPtr >= 3
|
||||
&& (dataBuffer[dataPtr - 3] == (byte) 0xDE
|
||||
|| dataBuffer[dataPtr - 3] == (byte) 0xDA) // non-standard
|
||||
&& dataBuffer[dataPtr - 2] == (byte) 0xAA;
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
this.disk = dosDisk.getDisk ();
|
||||
this.catalogSectorDA = catalogSector;
|
||||
|
||||
// reportedSize = HexFormatter.intValue (entryBuffer[33], entryBuffer[34]);
|
||||
reportedSize = HexFormatter.unsignedShort (entryBuffer, 33);
|
||||
int type = entryBuffer[2] & 0xFF;
|
||||
locked = (type & 0x80) > 0;
|
||||
@ -184,16 +183,11 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
|
||||
// buffer is a multiple of the block size, so it usually needs to be reduced
|
||||
if ((reportedLength + 4) <= buffer.length)
|
||||
{
|
||||
exactBuffer = new byte[reportedLength];
|
||||
// extraBuffer = new byte[buffer.length - reportedLength - 4];
|
||||
// System.arraycopy (buffer, reportedLength + 4, extraBuffer, 0,
|
||||
// extraBuffer.length);
|
||||
}
|
||||
else
|
||||
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
|
||||
|
||||
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
|
||||
|
||||
if ((name.endsWith (".FONT") || name.endsWith (" FONT")
|
||||
|| name.endsWith (".SET") || name.startsWith ("ASCII."))
|
||||
&& FontFile.isFont (exactBuffer))
|
||||
@ -278,9 +272,6 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
{
|
||||
byte[] exactBuffer;
|
||||
|
||||
// int loadAddress = HexFormatter.intValue (buffer[0], buffer[1]);
|
||||
// int loadAddress = HexFormatter.unsignedShort (buffer, 0);
|
||||
// int reportedLength = HexFormatter.intValue (buffer[2], buffer[3]);
|
||||
int reportedLength = HexFormatter.unsignedShort (buffer, 2);
|
||||
if (reportedLength == 0)
|
||||
{
|
||||
@ -291,15 +282,11 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
|
||||
// buffer is a multiple of the block size, so it usually needs to be reduced
|
||||
if ((reportedLength + 4) <= buffer.length)
|
||||
{
|
||||
exactBuffer = new byte[reportedLength];
|
||||
// extraBuffer = new byte[buffer.length - reportedLength - 4];
|
||||
// System.arraycopy (buffer, reportedLength + 4, extraBuffer, 0,
|
||||
// extraBuffer.length);
|
||||
}
|
||||
else
|
||||
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
|
||||
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
|
||||
|
||||
return exactBuffer;
|
||||
}
|
||||
|
||||
@ -309,9 +296,6 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
&& reportedLength == 0x14FA)
|
||||
return true;
|
||||
|
||||
// if (name.endsWith (".PAC"))
|
||||
// return true;
|
||||
|
||||
if (name.equals ("BBROS LOGO SCRUNCHED") && reportedLength == 0x0FED)
|
||||
return true;
|
||||
|
||||
@ -324,10 +308,13 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
for (DiskAddress sector : tsSectors)
|
||||
if (sector.matches (da))
|
||||
return true;
|
||||
|
||||
for (DiskAddress sector : dataSectors)
|
||||
// random access files may have gaps, and thus null sectors
|
||||
// is this still true? I thought I was using sector zero objects??
|
||||
if (sector != null && sector.matches (da))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.prefs.Preferences;
|
||||
@ -126,13 +128,37 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
||||
addQuitListener (catalogPanel);
|
||||
addQuitListener (this);
|
||||
|
||||
Desktop desktop = Desktop.getDesktop ();
|
||||
desktop.setAboutHandler (e -> JOptionPane.showMessageDialog (null,
|
||||
"Author - Denis Molony\nGitHub - https://github.com/dmolony/DiskBrowser",
|
||||
"About DiskBrowser", JOptionPane.INFORMATION_MESSAGE));
|
||||
// desktop.setPreferencesHandler (
|
||||
// e -> JOptionPane.showMessageDialog (null, "Preferences dialog"));
|
||||
desktop.setQuitHandler ( (e, r) -> fireQuitEvent ());
|
||||
if (Desktop.isDesktopSupported ())
|
||||
{
|
||||
Desktop desktop = Desktop.getDesktop ();
|
||||
if (false)
|
||||
{
|
||||
System.out.println ("Enums:");
|
||||
for (Desktop.Action a : Desktop.Action.values ())
|
||||
System.out.printf ("%s is%s supported%n", a.toString (),
|
||||
(desktop.isSupported (a) ? "" : " not"));
|
||||
}
|
||||
|
||||
if (desktop.isSupported (Desktop.Action.APP_ABOUT))
|
||||
desktop.setAboutHandler (e -> JOptionPane.showMessageDialog (null,
|
||||
"Author - Denis Molony\nGitHub - https://github.com/dmolony/DiskBrowser",
|
||||
"About DiskBrowser", JOptionPane.INFORMATION_MESSAGE));
|
||||
if (desktop.isSupported (Desktop.Action.APP_QUIT_HANDLER))
|
||||
desktop.setQuitHandler ( (e, r) -> fireQuitEvent ());
|
||||
else
|
||||
{
|
||||
addWindowListener (new WindowAdapter ()
|
||||
{
|
||||
@Override
|
||||
public void windowClosing (WindowEvent e)
|
||||
{
|
||||
fireQuitEvent ();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
System.out.println ("Desktop not supported");
|
||||
|
||||
catalogPanel.setCloseTabAction (closeTabAction);
|
||||
|
||||
|
@ -354,9 +354,12 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
file = new SHRPictureFile2 (name, exactBuffer, fileType, auxType, endOfFile);
|
||||
break;
|
||||
|
||||
case FILE_TYPE_PICT:
|
||||
System.out.println ("*** PICT : " + name);
|
||||
file = new DefaultAppleFile (name, exactBuffer);
|
||||
case FILE_TYPE_FOT:
|
||||
if (auxType == 0x8066) // Fadden
|
||||
// file = new DefaultAppleFile (name, exactBuffer);
|
||||
file = new FaddenHiResImage (name, exactBuffer, fileType, auxType, endOfFile);
|
||||
else
|
||||
file = new DefaultAppleFile (name, exactBuffer);
|
||||
break;
|
||||
|
||||
case FILE_TYPE_FONT:
|
||||
@ -424,6 +427,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
// Text files with aux (reclen) > 0 are random access, possibly with
|
||||
// non-contiguous records, so they need to be handled differently
|
||||
|
||||
// Graphics files can also have gaps
|
||||
|
||||
switch (storageType)
|
||||
{
|
||||
case TREE:
|
||||
@ -529,65 +534,6 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
}
|
||||
}
|
||||
|
||||
// should be removed
|
||||
// private byte[] getGEOSBuffer ()
|
||||
// {
|
||||
// switch (storageType)
|
||||
// {
|
||||
// case SEEDLING:
|
||||
// System.out.println ("Seedling GEOS file : " + name); // not sure if possible
|
||||
// return disk.readSectors (dataBlocks);
|
||||
// case SAPLING:
|
||||
// return getIndexFile (keyPtr);
|
||||
// case TREE:
|
||||
// return getMasterIndexFile (keyPtr);
|
||||
// default:
|
||||
// System.out.println ("Unknown storage type for GEOS file : " + storageType);
|
||||
// return new byte[512];
|
||||
// }
|
||||
// }
|
||||
|
||||
// should be removed
|
||||
// private byte[] getMasterIndexFile (int keyPtr)
|
||||
// {
|
||||
// byte[] buffer = disk.readSector (keyPtr);
|
||||
// int length = HexFormatter.intValue (buffer[0xFF], buffer[0x1FF]);
|
||||
// byte[] fileBuffer = new byte[length];
|
||||
// int ptr = 0;
|
||||
// for (int i = 0; i < 0x80; i++)
|
||||
// {
|
||||
// int block = HexFormatter.intValue (buffer[i], buffer[i + 256]);
|
||||
// if (block == 0)
|
||||
// break;
|
||||
// if (block == 0xFFFF) // should this insert 131,072 zeroes?
|
||||
// continue;
|
||||
// byte[] temp = getIndexFile (block);
|
||||
// System.arraycopy (temp, 0, fileBuffer, ptr, temp.length);
|
||||
// ptr += temp.length;
|
||||
// }
|
||||
// return fileBuffer;
|
||||
// }
|
||||
|
||||
// should be removed
|
||||
// private byte[] getIndexFile (int keyPtr)
|
||||
// {
|
||||
// byte[] buffer = disk.readSector (keyPtr);
|
||||
// int length = HexFormatter.intValue (buffer[0xFF], buffer[0x1FF]);
|
||||
// byte[] fileBuffer = new byte[length];
|
||||
// for (int i = 0; i < 0x80; i++)
|
||||
// {
|
||||
// int block = HexFormatter.intValue (buffer[i], buffer[i + 256]);
|
||||
// if (block == 0)
|
||||
// break;
|
||||
// if (block == 0xFFFF) // should this insert 512 zeroes?
|
||||
// continue;
|
||||
// byte[] temp = disk.readSector (block);
|
||||
// System.arraycopy (temp, 0, fileBuffer, i * 512, length > 512 ? 512 : length);
|
||||
// length -= 512;
|
||||
// }
|
||||
// return fileBuffer;
|
||||
// }
|
||||
|
||||
private int readIndexBlock (int indexBlock, List<DiskAddress> addresses,
|
||||
List<TextBuffer> buffers, int logicalBlock)
|
||||
{
|
||||
@ -648,11 +594,12 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
{
|
||||
if (ProdosConstants.fileTypes[fileType].equals ("DIR"))
|
||||
return name;
|
||||
// String locked = (access == 0x01) ? "*" : " ";
|
||||
String locked = (access == 0x00) ? "*" : " ";
|
||||
|
||||
if (true)
|
||||
return String.format ("%s %03d %s", ProdosConstants.fileTypes[fileType],
|
||||
blocksUsed, locked) + name;
|
||||
|
||||
String timeC = created == null ? "" : parentDisk.df.format (created.getTime ());
|
||||
String timeF = modified == null ? "" : parentDisk.df.format (modified.getTime ());
|
||||
return String.format ("%s %s%-30s %3d %,10d %15s %15s",
|
||||
|
@ -4,7 +4,7 @@ public interface ProdosConstants
|
||||
{
|
||||
int FILE_TYPE_TEXT = 0x04;
|
||||
int FILE_TYPE_BINARY = 0x06;
|
||||
int FILE_TYPE_PICT = 0x08; // was Apple /// FotoFile
|
||||
int FILE_TYPE_FOT = 0x08; // was Apple /// FotoFile
|
||||
int FILE_TYPE_DIRECTORY = 0x0F;
|
||||
int FILE_TYPE_ADB = 0x19;
|
||||
int FILE_TYPE_AWP = 0x1A;
|
||||
|
@ -87,19 +87,12 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
|
||||
case FILE_TYPE_BINARY:
|
||||
case FILE_TYPE_PNT:
|
||||
case FILE_TYPE_PIC:
|
||||
case FILE_TYPE_FOT:
|
||||
aux = HexFormatter.intValue (buffer[i + 31], buffer[i + 32]);
|
||||
subType = String.format ("A=$%4X", aux);
|
||||
// if (fileType == FILE_TYPE_PNT && aux == 0)
|
||||
// System.out.printf ("found $C0/00 %s%n", name);
|
||||
// if (fileType == FILE_TYPE_PNT && aux == 3)
|
||||
// System.out.printf ("found $C0/03 %s%n", name);
|
||||
// if (fileType == FILE_TYPE_PNT && aux == 4)
|
||||
// System.out.printf ("found $C0/04 %s%n", name);
|
||||
// if (fileType == FILE_TYPE_PIC && aux == 1)
|
||||
// System.out.printf ("found $C1/01 %s%n", name);
|
||||
break;
|
||||
|
||||
case 0x1A: // AWP file
|
||||
case FILE_TYPE_AWP:
|
||||
aux = HexFormatter.intValue (buffer[i + 32], buffer[i + 31]); // backwards!
|
||||
if (aux != 0)
|
||||
filename = convert (filename, aux);
|
||||
|
Loading…
x
Reference in New Issue
Block a user