mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2025-02-08 17:30:40 +00:00
DOS Double hi-res
This commit is contained in:
parent
491603247a
commit
abdaa41060
@ -14,6 +14,7 @@ public abstract class AbstractFile implements DataSource
|
||||
public byte[] buffer;
|
||||
protected AssemblerProgram assembler;
|
||||
protected BufferedImage image;
|
||||
protected int loadAddress;
|
||||
|
||||
public AbstractFile (String name, byte[] buffer)
|
||||
{
|
||||
@ -39,7 +40,7 @@ public abstract class AbstractFile implements DataSource
|
||||
return "No buffer";
|
||||
|
||||
if (assembler == null)
|
||||
this.assembler = new AssemblerProgram (name, buffer, 0);
|
||||
this.assembler = new AssemblerProgram (name, buffer, loadAddress);
|
||||
|
||||
return assembler.getText ();
|
||||
}
|
||||
|
98
src/com/bytezone/diskbrowser/applefile/DoubleHiResImage.java
Normal file
98
src/com/bytezone/diskbrowser/applefile/DoubleHiResImage.java
Normal file
@ -0,0 +1,98 @@
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
|
||||
public class DoubleHiResImage extends HiResImage
|
||||
{
|
||||
private static final int BLACK = 0x000000;
|
||||
private static final int MAGENTA = 0xFF00FF;
|
||||
private static final int BROWN = 0x994C00;
|
||||
private static final int ORANGE = 0xFF9933;
|
||||
private static final int DARK_GREEN = 0x006600;
|
||||
private static final int GRAY = 0xA0A0A0;
|
||||
private static final int GREEN = 0x00CC00;
|
||||
private static final int YELLOW = 0xFFFF33;
|
||||
private static final int DARK_BLUE = 0x0066CC;
|
||||
private static final int PURPLE = 0xCC00CC;
|
||||
private static final int PINK = 0xFFCCE5;
|
||||
private static final int MEDIUM_BLUE = 0x3399FF;
|
||||
private static final int LIGHT_BLUE = 0x99CCFF;
|
||||
private static final int AQUA = 0x99FFFF;
|
||||
private static final int WHITE = 0xFFFFFF;
|
||||
|
||||
private static int[] palette =
|
||||
{ BLACK, MAGENTA, BROWN, ORANGE, DARK_GREEN, GRAY, GREEN, YELLOW, DARK_BLUE, PURPLE,
|
||||
GRAY, PINK, MEDIUM_BLUE, LIGHT_BLUE, AQUA, WHITE };
|
||||
|
||||
private final byte[] auxBuffer;
|
||||
|
||||
public DoubleHiResImage (String name, byte[] buffer, byte[] auxBuffer)
|
||||
{
|
||||
super (name, buffer);
|
||||
|
||||
this.auxBuffer = auxBuffer;
|
||||
|
||||
createImage ();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMonochromeImage ()
|
||||
{
|
||||
// image will be doubled vertically
|
||||
image = new BufferedImage (560, 192 * 2, BufferedImage.TYPE_BYTE_GRAY);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
int base = i * 0x28 + j * 0x80 + k * 0x400;
|
||||
int max = Math.min (base + 40, buffer.length);
|
||||
for (int ptr = base; ptr < max; ptr += 2)
|
||||
{
|
||||
int value = auxBuffer[ptr] & 0x7F | ((buffer[ptr] & 0x7F) << 7)
|
||||
| ((auxBuffer[ptr + 1] & 0x7F) << 14) | ((buffer[ptr + 1] & 0x7F) << 21);
|
||||
for (int px = 0; px < 28; px++)
|
||||
{
|
||||
int val = (value >> px) & 0x01;
|
||||
int pixel = val == 0 ? 0 : 255;
|
||||
dataBuffer.setElem (element, pixel);
|
||||
dataBuffer.setElem (element + 560, pixel); // repeat pixel one line on
|
||||
++element;
|
||||
}
|
||||
}
|
||||
element += 560; // skip past repeated line
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createColourImage ()
|
||||
{
|
||||
// image will be doubled horizontally
|
||||
image = new BufferedImage (140 * 2, 192, BufferedImage.TYPE_INT_RGB);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
int base = i * 0x28 + j * 0x80 + k * 0x400;
|
||||
int max = Math.min (base + 40, buffer.length);
|
||||
|
||||
for (int ptr = base; ptr < max; ptr += 2)
|
||||
{
|
||||
int value = auxBuffer[ptr] & 0x7F | ((buffer[ptr] & 0x7F) << 7)
|
||||
| ((auxBuffer[ptr + 1] & 0x7F) << 14) | ((buffer[ptr + 1] & 0x7F) << 21);
|
||||
for (int px = 0; px < 28; px += 4)
|
||||
{
|
||||
int val = (value >> px) & 0x0F;
|
||||
dataBuffer.setElem (element++, palette[val]);
|
||||
dataBuffer.setElem (element++, palette[val]); // repeat pixel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
722
src/com/bytezone/diskbrowser/applefile/HiResImage.java
Executable file → Normal file
722
src/com/bytezone/diskbrowser/applefile/HiResImage.java
Executable file → Normal file
@ -1,409 +1,315 @@
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
|
||||
public class HiResImage extends AbstractFile
|
||||
{
|
||||
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[][] palette = { { VIOLET, GREEN }, { BLUE, RED } };
|
||||
private static final byte[] pngHeader =
|
||||
{ (byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
|
||||
|
||||
private static boolean colourQuirks;
|
||||
private static boolean matchColourBits = false;
|
||||
private static boolean monochrome;
|
||||
|
||||
private final int[] line = new int[280];
|
||||
private final int[] colourBits = new int[280];
|
||||
|
||||
private int fileType;
|
||||
private int auxType;
|
||||
private byte[] unpackedBuffer;
|
||||
|
||||
public HiResImage (String name, byte[] buffer)
|
||||
{
|
||||
this (name, buffer, false);
|
||||
}
|
||||
|
||||
public HiResImage (String name, byte[] buffer, boolean scrunched)
|
||||
{
|
||||
super (name, buffer);
|
||||
|
||||
if (scrunched)
|
||||
this.buffer = unscrunch (buffer);
|
||||
|
||||
draw ();
|
||||
}
|
||||
|
||||
private void draw ()
|
||||
{
|
||||
if (isGif (buffer) || isPng (buffer))
|
||||
makeImage ();
|
||||
else if (monochrome)
|
||||
drawMonochrome (buffer);
|
||||
else
|
||||
drawColour (buffer);
|
||||
}
|
||||
|
||||
public HiResImage (String name, byte[] buffer, int fileType, int auxType)
|
||||
{
|
||||
super (name, buffer);
|
||||
this.fileType = fileType;
|
||||
this.auxType = auxType;
|
||||
|
||||
if (fileType == 0xC0 && auxType == 1)
|
||||
{
|
||||
unpackedBuffer = unpackBytes (buffer);
|
||||
makeScreen2 (unpackedBuffer);
|
||||
}
|
||||
|
||||
if (fileType == 0xC0 && auxType == 2)
|
||||
System.out.println ("yippee - Preferred picture format - " + name);
|
||||
}
|
||||
|
||||
public static void setDefaultColourQuirks (boolean value)
|
||||
{
|
||||
colourQuirks = value;
|
||||
}
|
||||
|
||||
public static void setDefaultMonochrome (boolean value)
|
||||
{
|
||||
monochrome = value;
|
||||
}
|
||||
|
||||
public void setColourQuirks (boolean value)
|
||||
{
|
||||
if (colourQuirks == value)
|
||||
return;
|
||||
|
||||
colourQuirks = value;
|
||||
|
||||
if (!monochrome)
|
||||
draw ();
|
||||
}
|
||||
|
||||
public void setMonochrome (boolean value)
|
||||
{
|
||||
if (monochrome == value)
|
||||
return;
|
||||
|
||||
monochrome = value;
|
||||
draw ();
|
||||
}
|
||||
|
||||
private void drawMonochrome (byte[] buffer)
|
||||
{
|
||||
int rows = buffer.length <= 8192 ? 192 : 384;
|
||||
image = new BufferedImage (280, rows, BufferedImage.TYPE_BYTE_GRAY);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
|
||||
for (int page = 0; page < rows / 192; page++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
int base = page * 0x2000 + i * 0x28 + j * 0x80 + k * 0x400;
|
||||
int max = Math.min (base + 40, buffer.length);
|
||||
for (int ptr = base; ptr < max; ptr++)
|
||||
{
|
||||
int value = buffer[ptr] & 0x7F;
|
||||
for (int px = 0; px < 7; px++)
|
||||
{
|
||||
int val = (value >> px) & 0x01;
|
||||
dataBuffer.setElem (element++, val == 0 ? 0 : 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawColour (byte[] buffer)
|
||||
{
|
||||
int rows = buffer.length <= 8192 ? 192 : 384;
|
||||
image = new BufferedImage (280, rows, BufferedImage.TYPE_INT_RGB);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
|
||||
for (int page = 0; page < rows / 192; page++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
fillLine (page * 0x2000 + i * 0x28 + j * 0x80 + k * 0x400);
|
||||
for (int pixel : line)
|
||||
dataBuffer.setElem (element++, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillLine (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++)
|
||||
{
|
||||
colourBits[linePtr] = colourBit; // store the colour bit
|
||||
int val = (value >> px) & 0x01; // get the next pixel to draw
|
||||
int column = (ptr + px) % 2; // is it in an odd or even column?
|
||||
line[linePtr++] = val == 0 ? 0 : // black pixel
|
||||
palette[colourBit][column]; // coloured pixel - use lookup table
|
||||
}
|
||||
}
|
||||
|
||||
// convert consecutive ON pixels to white
|
||||
for (int x = 1; x < line.length; x++) // skip first pixel, refer back
|
||||
{
|
||||
if (matchColourBits && colourBits[x - 1] != colourBits[x])
|
||||
continue; // only modify values with matching colour bits
|
||||
|
||||
int px0 = line[x - 1];
|
||||
int px1 = line[x];
|
||||
if (px0 != BLACK && px1 != BLACK)
|
||||
line[x - 1] = line[x] = WHITE;
|
||||
}
|
||||
|
||||
// optionally do physics
|
||||
if (colourQuirks)
|
||||
applyColourQuirks ();
|
||||
}
|
||||
|
||||
private boolean isColoured (int pixel)
|
||||
{
|
||||
return pixel != BLACK && pixel != WHITE;
|
||||
}
|
||||
|
||||
private void applyColourQuirks ()
|
||||
{
|
||||
for (int x = 3; x < line.length; x++) // skip first three pixels, refer back
|
||||
{
|
||||
if (matchColourBits && colourBits[x - 2] != colourBits[x - 1])
|
||||
continue; // only modify values with matching colour bits
|
||||
|
||||
int px0 = line[x - 3];
|
||||
int px1 = line[x - 2];
|
||||
int px2 = line[x - 1];
|
||||
int px3 = line[x];
|
||||
|
||||
if (px1 == BLACK)
|
||||
{
|
||||
if (px3 == BLACK && px0 == px2 && isColoured (px0)) // V-B-V-B
|
||||
line[x - 2] = px0; // --> V-V-V-B
|
||||
else if (px3 == WHITE && px2 == WHITE && isColoured (px0)) // V-B-W-W
|
||||
line[x - 2] = px0; // --> V-V-W-W
|
||||
}
|
||||
else if (px2 == BLACK)
|
||||
{
|
||||
if (px0 == BLACK && px1 == px3 && isColoured (px3)) // B-G-B-G
|
||||
line[x - 1] = px3; // --> B-G-G-G
|
||||
else if (px0 == WHITE && px1 == WHITE && isColoured (px3)) // W-W-B-G
|
||||
line[x - 1] = px3; // --> W-W-G-G
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void makeScreen2 (byte[] buffer)
|
||||
{
|
||||
// System.out.println (HexFormatter.format (buffer, 32000, 640));
|
||||
// for (int table = 0; table < 200; table++)
|
||||
// {
|
||||
// System.out.println (HexFormatter.format (buffer, ptr, 32));
|
||||
// for (int color = 0; color < 16; color++)
|
||||
// {
|
||||
// int red = buffer[ptr++] & 0x0F;
|
||||
// int green = (buffer[ptr] & 0xF0) >> 4;
|
||||
// int blue = buffer[ptr++] & 0x0F;
|
||||
// Color c = new Color (red, green, blue);
|
||||
// }
|
||||
// }
|
||||
|
||||
image = new BufferedImage (320, 200, BufferedImage.TYPE_BYTE_GRAY);
|
||||
DataBuffer db = image.getRaster ().getDataBuffer ();
|
||||
|
||||
int element = 0;
|
||||
int ptr = 0;
|
||||
for (int row = 0; row < 200; row++)
|
||||
for (int col = 0; col < 160; col++)
|
||||
{
|
||||
int pix1 = (buffer[ptr] & 0xF0) >> 4;
|
||||
int pix2 = buffer[ptr] & 0x0F;
|
||||
if (pix1 > 0)
|
||||
db.setElem (element, 255);
|
||||
if (pix2 > 0)
|
||||
db.setElem (element + 1, 255);
|
||||
element += 2;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
// Beagle Bros routine to expand a hi-res screen
|
||||
private byte[] unscrunch (byte[] src)
|
||||
{
|
||||
byte[] dst = new byte[0x2000];
|
||||
int p1 = 0;
|
||||
int p2 = 0;
|
||||
|
||||
while (p1 < dst.length)
|
||||
{
|
||||
byte b = src[p2++];
|
||||
if ((b == (byte) 0x80) || (b == (byte) 0xFF))
|
||||
{
|
||||
b &= 0x7F;
|
||||
int rpt = src[p2++];
|
||||
for (int i = 0; i < rpt; i++)
|
||||
dst[p1++] = b;
|
||||
}
|
||||
else
|
||||
dst[p1++] = b;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
private void makeImage ()
|
||||
{
|
||||
try
|
||||
{
|
||||
image = ImageIO.read (new ByteArrayInputStream (buffer));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace ();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] unpackBytes (byte[] buffer)
|
||||
{
|
||||
// routine found here - http://kpreid.livejournal.com/4319.html
|
||||
|
||||
byte[] newBuf = new byte[32768];
|
||||
byte[] fourBuf = new byte[4];
|
||||
|
||||
int ptr = 0, newPtr = 0;
|
||||
while (ptr < buffer.length)
|
||||
{
|
||||
int type = (buffer[ptr] & 0xC0) >> 6;
|
||||
int count = (buffer[ptr++] & 0x3F) + 1;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
while (count-- != 0)
|
||||
newBuf[newPtr++] = buffer[ptr++];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
byte b = buffer[ptr++];
|
||||
while (count-- != 0)
|
||||
newBuf[newPtr++] = b;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int i = 0; i < 4; i++)
|
||||
fourBuf[i] = buffer[ptr++];
|
||||
while (count-- != 0)
|
||||
for (int i = 0; i < 4; i++)
|
||||
newBuf[newPtr++] = fourBuf[i];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
b = buffer[ptr++];
|
||||
count *= 4;
|
||||
while (count-- != 0)
|
||||
newBuf[newPtr++] = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText ()
|
||||
{
|
||||
String auxText = "";
|
||||
StringBuilder text = new StringBuilder ("Image File : " + name);
|
||||
text.append (String.format ("%nFile type : $%02X", fileType));
|
||||
|
||||
switch (fileType)
|
||||
{
|
||||
case 8:
|
||||
if (auxType < 0x4000)
|
||||
auxText = "Graphics File";
|
||||
else if (auxType == 0x4000)
|
||||
auxText = "Packed Hi-Res File";
|
||||
else if (auxType == 0x4001)
|
||||
auxText = "Packed Double Hi-Res File";
|
||||
break;
|
||||
|
||||
case 192:
|
||||
if (auxType == 1)
|
||||
{
|
||||
if (unpackedBuffer == null)
|
||||
unpackedBuffer = unpackBytes (buffer);
|
||||
auxText = "Packed Super Hi-Res Image";
|
||||
}
|
||||
else if (auxType == 2)
|
||||
auxText = "Super Hi-Res Image";
|
||||
else if (auxType == 3)
|
||||
auxText = "Packed QuickDraw II PICT File";
|
||||
break;
|
||||
|
||||
case 193:
|
||||
if (auxType == 0)
|
||||
auxText = "Super Hi-res Screen Image";
|
||||
else if (auxType == 1)
|
||||
auxText = "QuickDraw PICT File";
|
||||
else if (auxType == 2)
|
||||
auxText = "Super Hi-Res 3200 color image";
|
||||
}
|
||||
|
||||
if (!auxText.isEmpty ())
|
||||
text.append (String.format ("%nAux type : $%04X %s", auxType, auxText));
|
||||
|
||||
text.append (String.format ("%nFile size : %,d", buffer.length));
|
||||
if (unpackedBuffer != null)
|
||||
{
|
||||
text.append (String.format ("%nUnpacked : %,d%n%n", unpackedBuffer.length));
|
||||
text.append (HexFormatter.format (unpackedBuffer));
|
||||
}
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
public static boolean isGif (byte[] buffer)
|
||||
{
|
||||
if (buffer.length < 6)
|
||||
return false;
|
||||
|
||||
String text = new String (buffer, 0, 6);
|
||||
return text.equals ("GIF89a") || text.equals ("GIF87a");
|
||||
}
|
||||
|
||||
public static boolean isPng (byte[] buffer)
|
||||
{
|
||||
if (buffer.length < pngHeader.length)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < pngHeader.length; i++)
|
||||
if (pngHeader[i] != buffer[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.bytezone.diskbrowser.prodos.ProdosConstants;
|
||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
|
||||
public abstract class HiResImage extends AbstractFile
|
||||
{
|
||||
private static final byte[] pngHeader =
|
||||
{ (byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
|
||||
|
||||
protected static boolean colourQuirks;
|
||||
protected static boolean monochrome;
|
||||
|
||||
protected int fileType;
|
||||
protected int auxType;
|
||||
protected byte[] unpackedBuffer;
|
||||
|
||||
public HiResImage (String name, byte[] buffer)
|
||||
{
|
||||
super (name, buffer);
|
||||
}
|
||||
|
||||
public HiResImage (String name, byte[] buffer, int loadAddress)
|
||||
{
|
||||
this (name, buffer, loadAddress, false);
|
||||
}
|
||||
|
||||
public HiResImage (String name, byte[] buffer, int loadAddress, boolean scrunched)
|
||||
{
|
||||
super (name, buffer);
|
||||
|
||||
this.loadAddress = loadAddress; // for the disassembly listing
|
||||
|
||||
if (scrunched)
|
||||
this.buffer = unscrunch (buffer);
|
||||
}
|
||||
|
||||
public HiResImage (String name, byte[] buffer, int fileType, int auxType)
|
||||
{
|
||||
super (name, buffer);
|
||||
|
||||
this.fileType = fileType;
|
||||
this.auxType = auxType;
|
||||
|
||||
if (fileType == ProdosConstants.FILE_TYPE_PNT)
|
||||
{
|
||||
if (auxType == 1)
|
||||
{
|
||||
unpackedBuffer = unpackBytes (buffer);
|
||||
makeScreen2 (unpackedBuffer);
|
||||
System.out.println ("aux 1 - " + name);
|
||||
}
|
||||
|
||||
if (auxType == 2)
|
||||
{
|
||||
System.out.println ("aux 2 - " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void createImage ()
|
||||
{
|
||||
if (isGif (buffer) || isPng (buffer))
|
||||
makeImage ();
|
||||
else if (monochrome)
|
||||
createMonochromeImage ();
|
||||
else
|
||||
createColourImage ();
|
||||
}
|
||||
|
||||
protected abstract void createMonochromeImage ();
|
||||
|
||||
protected abstract void createColourImage ();
|
||||
|
||||
public void setColourQuirks (boolean value)
|
||||
{
|
||||
if (colourQuirks == value)
|
||||
return;
|
||||
|
||||
colourQuirks = value;
|
||||
|
||||
if (!monochrome)
|
||||
createImage ();
|
||||
}
|
||||
|
||||
public void setMonochrome (boolean value)
|
||||
{
|
||||
if (monochrome == value)
|
||||
return;
|
||||
|
||||
monochrome = value;
|
||||
createImage ();
|
||||
}
|
||||
|
||||
public static void setDefaultColourQuirks (boolean value)
|
||||
{
|
||||
colourQuirks = value;
|
||||
}
|
||||
|
||||
public static void setDefaultMonochrome (boolean value)
|
||||
{
|
||||
monochrome = value;
|
||||
}
|
||||
|
||||
/*-
|
||||
Mode Page 1 Page 2
|
||||
280 x 192 Black & White 0 4
|
||||
280 x 192 Limited Color 1 5
|
||||
560 x 192 Black & White 2 6
|
||||
140 x 192 Full Color 3 7
|
||||
*/
|
||||
|
||||
// SHR see - http://noboot.com/charlie/cb2e_p3.htm
|
||||
|
||||
@Override
|
||||
public String getText ()
|
||||
{
|
||||
String auxText = "";
|
||||
StringBuilder text = new StringBuilder ("Image File : " + name);
|
||||
text.append (String.format ("%nFile type : $%02X", fileType));
|
||||
|
||||
switch (fileType)
|
||||
{
|
||||
case ProdosConstants.FILE_TYPE_PICT:
|
||||
if (auxType < 0x4000)
|
||||
{
|
||||
auxText = "Graphics File";
|
||||
byte mode = buffer[0x78]; // 0-7
|
||||
System.out.println ("Prodos PICT, mode=" + mode);
|
||||
}
|
||||
else if (auxType == 0x4000)
|
||||
auxText = "Packed Hi-Res File";
|
||||
else if (auxType == 0x4001)
|
||||
auxText = "Packed Double Hi-Res File";
|
||||
break;
|
||||
|
||||
case ProdosConstants.FILE_TYPE_PNT:
|
||||
if (auxType == 1)
|
||||
{
|
||||
if (unpackedBuffer == null)
|
||||
unpackedBuffer = unpackBytes (buffer);
|
||||
auxText = "Packed Super Hi-Res Image";
|
||||
}
|
||||
else if (auxType == 2)
|
||||
auxText = "Super Hi-Res Image";
|
||||
else if (auxType == 3)
|
||||
auxText = "Packed QuickDraw II PICT File";
|
||||
break;
|
||||
|
||||
case ProdosConstants.FILE_TYPE_PIC:
|
||||
if (auxType == 0)
|
||||
auxText = "Super Hi-res Screen Image";
|
||||
else if (auxType == 1)
|
||||
auxText = "QuickDraw PICT File";
|
||||
else if (auxType == 2)
|
||||
auxText = "Super Hi-Res 3200 color image";
|
||||
}
|
||||
|
||||
if (!auxText.isEmpty ())
|
||||
text.append (String.format ("%nAux type : $%04X %s", auxType, auxText));
|
||||
|
||||
text.append (String.format ("%nFile size : %,d", buffer.length));
|
||||
if (unpackedBuffer != null)
|
||||
{
|
||||
text.append (String.format ("%nUnpacked : %,d%n%n", unpackedBuffer.length));
|
||||
text.append (HexFormatter.format (unpackedBuffer));
|
||||
}
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
protected void makeScreen2 (byte[] buffer)
|
||||
{
|
||||
// System.out.println (HexFormatter.format (buffer, 32000, 640));
|
||||
// for (int table = 0; table < 200; table++)
|
||||
// {
|
||||
// System.out.println (HexFormatter.format (buffer, ptr, 32));
|
||||
// for (int color = 0; color < 16; color++)
|
||||
// {
|
||||
// int red = buffer[ptr++] & 0x0F;
|
||||
// int green = (buffer[ptr] & 0xF0) >> 4;
|
||||
// int blue = buffer[ptr++] & 0x0F;
|
||||
// Color c = new Color (red, green, blue);
|
||||
// }
|
||||
// }
|
||||
|
||||
image = new BufferedImage (320, 200, BufferedImage.TYPE_BYTE_GRAY);
|
||||
DataBuffer db = image.getRaster ().getDataBuffer ();
|
||||
|
||||
int element = 0;
|
||||
int ptr = 0;
|
||||
for (int row = 0; row < 200; row++)
|
||||
for (int col = 0; col < 160; col++)
|
||||
{
|
||||
int pix1 = (buffer[ptr] & 0xF0) >> 4;
|
||||
int pix2 = buffer[ptr] & 0x0F;
|
||||
if (pix1 > 0)
|
||||
db.setElem (element, 255);
|
||||
if (pix2 > 0)
|
||||
db.setElem (element + 1, 255);
|
||||
element += 2;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
// Super Hi-res IIGS
|
||||
protected byte[] unpackBytes (byte[] buffer)
|
||||
{
|
||||
// routine found here - http://kpreid.livejournal.com/4319.html
|
||||
|
||||
byte[] newBuf = new byte[32768];
|
||||
byte[] fourBuf = new byte[4];
|
||||
|
||||
int ptr = 0, newPtr = 0;
|
||||
while (ptr < buffer.length)
|
||||
{
|
||||
int type = (buffer[ptr] & 0xC0) >> 6;
|
||||
int count = (buffer[ptr++] & 0x3F) + 1;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
while (count-- != 0)
|
||||
newBuf[newPtr++] = buffer[ptr++];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
byte b = buffer[ptr++];
|
||||
while (count-- != 0)
|
||||
newBuf[newPtr++] = b;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int i = 0; i < 4; i++)
|
||||
fourBuf[i] = buffer[ptr++];
|
||||
while (count-- != 0)
|
||||
for (int i = 0; i < 4; i++)
|
||||
newBuf[newPtr++] = fourBuf[i];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
b = buffer[ptr++];
|
||||
count *= 4;
|
||||
while (count-- != 0)
|
||||
newBuf[newPtr++] = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
// Beagle Bros routine to expand a hi-res screen
|
||||
private byte[] unscrunch (byte[] src)
|
||||
{
|
||||
byte[] dst = new byte[0x2000];
|
||||
int p1 = 0;
|
||||
int p2 = 0;
|
||||
|
||||
while (p1 < dst.length)
|
||||
{
|
||||
byte b = src[p2++];
|
||||
if ((b == (byte) 0x80) || (b == (byte) 0xFF))
|
||||
{
|
||||
b &= 0x7F;
|
||||
int rpt = src[p2++];
|
||||
for (int i = 0; i < rpt; i++)
|
||||
dst[p1++] = b;
|
||||
}
|
||||
else
|
||||
dst[p1++] = b;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
protected void makeImage ()
|
||||
{
|
||||
try
|
||||
{
|
||||
image = ImageIO.read (new ByteArrayInputStream (buffer));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace ();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isGif (byte[] buffer)
|
||||
{
|
||||
if (buffer.length < 6)
|
||||
return false;
|
||||
|
||||
String text = new String (buffer, 0, 6);
|
||||
return text.equals ("GIF89a") || text.equals ("GIF87a");
|
||||
}
|
||||
|
||||
public static boolean isPng (byte[] buffer)
|
||||
{
|
||||
if (buffer.length < pngHeader.length)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < pngHeader.length; i++)
|
||||
if (pngHeader[i] != buffer[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
160
src/com/bytezone/diskbrowser/applefile/OriginalHiResImage.java
Executable file
160
src/com/bytezone/diskbrowser/applefile/OriginalHiResImage.java
Executable file
@ -0,0 +1,160 @@
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
|
||||
public class OriginalHiResImage extends HiResImage
|
||||
{
|
||||
private static final int WHITE = 0xFFFFFF;
|
||||
private static final int BLACK = 0x000000;
|
||||
private static final int RED = 0xFF0000;
|
||||
private static final int GREEN = 0x00CC00;
|
||||
private static final int BLUE = 0x0000FF;
|
||||
private static final int VIOLET = 0xBB66FF;
|
||||
private static final int[][] palette = { { VIOLET, GREEN }, { BLUE, RED } };
|
||||
|
||||
private static boolean matchColourBits = false;
|
||||
|
||||
private final int[] line = new int[280];
|
||||
private final int[] colourBits = new int[280];
|
||||
|
||||
public OriginalHiResImage (String name, byte[] buffer, int loadAddress)
|
||||
{
|
||||
super (name, buffer, loadAddress);
|
||||
|
||||
createImage ();
|
||||
}
|
||||
|
||||
public OriginalHiResImage (String name, byte[] buffer, int loadAddress,
|
||||
boolean scrunched)
|
||||
{
|
||||
super (name, buffer, loadAddress, scrunched);
|
||||
|
||||
createImage ();
|
||||
}
|
||||
|
||||
public OriginalHiResImage (String name, byte[] buffer, int fileType, int auxType)
|
||||
{
|
||||
super (name, buffer, fileType, auxType);
|
||||
|
||||
// createImage ();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMonochromeImage ()
|
||||
{
|
||||
int rows = buffer.length <= 8192 ? 192 : 384;
|
||||
image = new BufferedImage (280, rows, BufferedImage.TYPE_BYTE_GRAY);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
|
||||
for (int page = 0; page < rows / 192; page++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
int base = page * 0x2000 + i * 0x28 + j * 0x80 + k * 0x400;
|
||||
int max = Math.min (base + 40, buffer.length);
|
||||
for (int ptr = base; ptr < max; ptr++)
|
||||
{
|
||||
int value = buffer[ptr] & 0x7F;
|
||||
for (int px = 0; px < 7; px++)
|
||||
{
|
||||
int val = (value >> px) & 0x01;
|
||||
dataBuffer.setElem (element++, val == 0 ? 0 : 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createColourImage ()
|
||||
{
|
||||
int rows = buffer.length <= 8192 ? 192 : 384;
|
||||
image = new BufferedImage (280, rows, BufferedImage.TYPE_INT_RGB);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
|
||||
for (int page = 0; page < rows / 192; page++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
fillLine (page * 0x2000 + i * 0x28 + j * 0x80 + k * 0x400);
|
||||
for (int pixel : line)
|
||||
dataBuffer.setElem (element++, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillLine (int base)
|
||||
{
|
||||
int max = Math.min (base + 40, buffer.length);
|
||||
int linePtr = 0;
|
||||
assert colourBits != null;
|
||||
|
||||
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++)
|
||||
{
|
||||
colourBits[linePtr] = colourBit; // store the colour bit
|
||||
int val = (value >> px) & 0x01; // get the next pixel to draw
|
||||
int column = (ptr + px) % 2; // is it in an odd or even column?
|
||||
line[linePtr++] = val == 0 ? 0 : // black pixel
|
||||
palette[colourBit][column]; // coloured pixel - use lookup table
|
||||
}
|
||||
}
|
||||
|
||||
// convert consecutive ON pixels to white
|
||||
for (int x = 1; x < line.length; x++) // skip first pixel, refer back
|
||||
{
|
||||
if (matchColourBits && colourBits[x - 1] != colourBits[x])
|
||||
continue; // only modify values with matching colour bits
|
||||
|
||||
int px0 = line[x - 1];
|
||||
int px1 = line[x];
|
||||
if (px0 != BLACK && px1 != BLACK)
|
||||
line[x - 1] = line[x] = WHITE;
|
||||
}
|
||||
|
||||
// optionally do physics
|
||||
if (colourQuirks)
|
||||
applyColourQuirks ();
|
||||
}
|
||||
|
||||
private boolean isColoured (int pixel)
|
||||
{
|
||||
return pixel != BLACK && pixel != WHITE;
|
||||
}
|
||||
|
||||
private void applyColourQuirks ()
|
||||
{
|
||||
for (int x = 3; x < line.length; x++) // skip first three pixels, refer back
|
||||
{
|
||||
if (matchColourBits && colourBits[x - 2] != colourBits[x - 1])
|
||||
continue; // only modify values with matching colour bits
|
||||
|
||||
int px0 = line[x - 3];
|
||||
int px1 = line[x - 2];
|
||||
int px2 = line[x - 1];
|
||||
int px3 = line[x];
|
||||
|
||||
if (px1 == BLACK)
|
||||
{
|
||||
if (px3 == BLACK && px0 == px2 && isColoured (px0)) // V-B-V-B
|
||||
line[x - 2] = px0; // --> V-V-V-B
|
||||
else if (px3 == WHITE && px2 == WHITE && isColoured (px0)) // V-B-W-W
|
||||
line[x - 2] = px0; // --> V-V-W-W
|
||||
}
|
||||
else if (px2 == BLACK)
|
||||
{
|
||||
if (px0 == BLACK && px1 == px3 && isColoured (px3)) // B-G-B-G
|
||||
line[x - 1] = px3; // --> B-G-G-G
|
||||
else if (px0 == WHITE && px1 == WHITE && isColoured (px3)) // W-W-B-G
|
||||
line[x - 1] = px3; // --> W-W-G-G
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -39,7 +39,10 @@
|
||||
00B7 CHRGOT
|
||||
00B8 TXTPTR
|
||||
|
||||
00E0 X of last HPLOT
|
||||
00E4 HCOLOR
|
||||
00E6 HiRes plotting page ($20 or $40)
|
||||
00E7 Scale
|
||||
00E8 Shape table address LO
|
||||
00E9 Shape table address HI
|
||||
00EA Collision counter
|
||||
|
@ -27,6 +27,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
protected final List<DiskAddress> dataSectors = new ArrayList<DiskAddress> ();
|
||||
protected final List<DiskAddress> tsSectors = new ArrayList<DiskAddress> ();
|
||||
|
||||
private CatalogEntry link;
|
||||
|
||||
public AbstractCatalogEntry (DosDisk dosDisk, DiskAddress catalogSector,
|
||||
byte[] entryBuffer)
|
||||
{
|
||||
@ -196,20 +198,30 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
|
||||
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
|
||||
|
||||
if (name.endsWith (".FONT") || name.endsWith (".SET"))
|
||||
if (name.endsWith (".FONT") || name.endsWith (" FONT")
|
||||
|| name.endsWith (".SET"))
|
||||
appleFile = new FontFile (name, exactBuffer);
|
||||
else if (ShapeTable.isShapeTable (exactBuffer))
|
||||
appleFile = new ShapeTable (name, exactBuffer);
|
||||
else if (name.endsWith (".S"))
|
||||
appleFile = new MerlinSource (name, exactBuffer);
|
||||
else if (HiResImage.isGif (exactBuffer))
|
||||
appleFile = new HiResImage (name, exactBuffer);
|
||||
appleFile = new OriginalHiResImage (name, exactBuffer, loadAddress);
|
||||
else if (link != null)
|
||||
{
|
||||
byte[] auxBuffer = link.disk.readSectors (link.dataSectors);
|
||||
byte[] exactAuxBuffer = getExactBuffer (auxBuffer);
|
||||
if (name.endsWith (".AUX"))
|
||||
appleFile = new DoubleHiResImage (name, exactAuxBuffer, exactBuffer);
|
||||
else
|
||||
appleFile = new DoubleHiResImage (name, exactBuffer, exactAuxBuffer);
|
||||
}
|
||||
else if (loadAddress == 0x2000 || loadAddress == 0x4000)
|
||||
{
|
||||
if (reportedLength > 0x1F00 && reportedLength <= 0x4000)
|
||||
appleFile = new HiResImage (name, exactBuffer);
|
||||
appleFile = new OriginalHiResImage (name, exactBuffer, loadAddress);
|
||||
else if (isScrunched (reportedLength))
|
||||
appleFile = new HiResImage (name, exactBuffer, true);
|
||||
appleFile = new OriginalHiResImage (name, exactBuffer, loadAddress, true);
|
||||
else
|
||||
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
|
||||
}
|
||||
@ -254,6 +266,33 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
return appleFile;
|
||||
}
|
||||
|
||||
private byte[] getExactBuffer (byte[] buffer)
|
||||
{
|
||||
byte[] exactBuffer;
|
||||
|
||||
int loadAddress = HexFormatter.intValue (buffer[0], buffer[1]);
|
||||
int reportedLength = HexFormatter.intValue (buffer[2], buffer[3]);
|
||||
if (reportedLength == 0)
|
||||
{
|
||||
System.out.println (
|
||||
name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
|
||||
reportedLength = buffer.length - 4;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
private boolean isScrunched (int reportedLength)
|
||||
{
|
||||
if ((name.equals ("FLY LOGO") || name.equals ("FLY LOGO SCRUNCHED"))
|
||||
@ -305,6 +344,11 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
||||
return sectors;
|
||||
}
|
||||
|
||||
void link (CatalogEntry catalogEntry)
|
||||
{
|
||||
this.link = catalogEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
|
@ -157,6 +157,24 @@ public class DosDisk extends AbstractFormattedDisk
|
||||
da = disk.getDiskAddress (sectorBuffer[1], sectorBuffer[2]);
|
||||
|
||||
} while (da.getBlock () != 0);
|
||||
// link double hi-res files
|
||||
for (AppleFileSource fe : fileEntries)
|
||||
{
|
||||
String name = fe.getUniqueName ();
|
||||
if (name.endsWith (".AUX"))
|
||||
{
|
||||
String partner1 = name.substring (0, name.length () - 4);
|
||||
String partner2 = partner1 + ".BIN";
|
||||
for (AppleFileSource fe2 : fileEntries)
|
||||
if (fe2.getUniqueName ().equals (partner1)
|
||||
|| fe2.getUniqueName ().equals (partner2))
|
||||
{
|
||||
// System.out.printf ("%s %s%n", name, partner1);
|
||||
((CatalogEntry) fe2).link ((CatalogEntry) fe);
|
||||
((CatalogEntry) fe).link ((CatalogEntry) fe2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add up all the free and used sectors, and label DOS sectors while we're here
|
||||
int lastDosSector = dosVTOCSector.maxSectors * 3; // first three tracks
|
||||
|
@ -30,6 +30,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
private DiskAddress masterIndexBlock;
|
||||
private final List<DiskAddress> indexBlocks = new ArrayList<DiskAddress> ();
|
||||
private boolean invalid;
|
||||
private FileEntry link;
|
||||
|
||||
public FileEntry (ProdosDisk fDisk, byte[] entryBuffer, DirectoryHeader parent,
|
||||
int parentBlock)
|
||||
@ -266,11 +267,18 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
else if (SimpleText.isHTML (exactBuffer))
|
||||
file = new SimpleText (name, exactBuffer);
|
||||
else if (HiResImage.isGif (exactBuffer))
|
||||
file = new HiResImage (name, exactBuffer);
|
||||
file = new OriginalHiResImage (name, exactBuffer, auxType);
|
||||
else if (link != null)
|
||||
{
|
||||
if (name.endsWith (".AUX"))
|
||||
file = new DoubleHiResImage (name, link.getBuffer (), exactBuffer);
|
||||
else
|
||||
file = new DoubleHiResImage (name, exactBuffer, link.getBuffer ());
|
||||
}
|
||||
else if ((endOfFile == 0x1FF8 || endOfFile == 0x1FFF || endOfFile == 0x2000
|
||||
|| endOfFile == 0x4000)
|
||||
&& (auxType == 0x1FFF || auxType == 0x2000 || auxType == 0x4000))
|
||||
file = new HiResImage (name, exactBuffer);
|
||||
file = new OriginalHiResImage (name, exactBuffer, auxType);
|
||||
else if (endOfFile == 38400 && name.startsWith ("LVL."))
|
||||
file = new LodeRunner (name, exactBuffer);
|
||||
else
|
||||
@ -282,7 +290,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
}
|
||||
break;
|
||||
case FILE_TYPE_TEXT:
|
||||
assert auxType == 0; // auxType > 0 handled above
|
||||
assert auxType == 0; // auxType > 0 handled above
|
||||
if (name.endsWith (".S"))
|
||||
file = new MerlinSource (name, exactBuffer, auxType, endOfFile);
|
||||
else
|
||||
@ -327,10 +335,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
file = new IconFile (name, exactBuffer);
|
||||
break;
|
||||
case FILE_TYPE_PNT:
|
||||
file = new HiResImage (name, exactBuffer, fileType, auxType);
|
||||
file = new OriginalHiResImage (name, exactBuffer, fileType, auxType);
|
||||
break;
|
||||
case FILE_TYPE_PIC:
|
||||
file = new HiResImage (name, exactBuffer, fileType, auxType);
|
||||
file = new OriginalHiResImage (name, exactBuffer, fileType, auxType);
|
||||
break;
|
||||
default:
|
||||
System.out.format ("Unknown file type : %02X%n", fileType);
|
||||
@ -551,6 +559,11 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
return false;
|
||||
}
|
||||
|
||||
void link (FileEntry fileEntry)
|
||||
{
|
||||
this.link = fileEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
|
@ -1,17 +1,17 @@
|
||||
package com.bytezone.diskbrowser.prodos;
|
||||
|
||||
interface ProdosConstants
|
||||
public interface ProdosConstants
|
||||
{
|
||||
int FILE_TYPE_TEXT = 0x04;
|
||||
int FILE_TYPE_BINARY = 0x06;
|
||||
int FILE_TYPE_PICT = 0x08;
|
||||
int FILE_TYPE_PICT = 0x08; // was Apple /// FotoFile
|
||||
int FILE_TYPE_DIRECTORY = 0x0F;
|
||||
int FILE_TYPE_ADB = 0x19;
|
||||
int FILE_TYPE_AWP = 0x1A;
|
||||
int FILE_TYPE_ASP = 0x1B;
|
||||
int FILE_TYPE_ASM_SOURCE = 0xB0;
|
||||
int FILE_TYPE_ASM_OBJECT = 0xB1;
|
||||
int FILE_TYPE_FORKED_FILE = 0xB3; // S16
|
||||
int FILE_TYPE_FORKED_FILE = 0xB3; // S16
|
||||
int FILE_TYPE_PNT = 0xC0;
|
||||
int FILE_TYPE_PIC = 0xC1;
|
||||
int FILE_TYPE_ICN = 0xCA;
|
||||
|
@ -146,6 +146,25 @@ public class ProdosDisk extends AbstractFormattedDisk
|
||||
}
|
||||
block = HexFormatter.intValue (sectorBuffer[2], sectorBuffer[3]);
|
||||
} while (block > 0);
|
||||
|
||||
// link double hi-res files
|
||||
for (AppleFileSource fe : fileEntries)
|
||||
{
|
||||
String name = fe.getUniqueName ();
|
||||
if (name.endsWith (".AUX"))
|
||||
{
|
||||
String partner1 = name.substring (0, name.length () - 4);
|
||||
String partner2 = name.substring (0, name.length () - 4) + ".BIN";
|
||||
for (AppleFileSource fe2 : fileEntries)
|
||||
if (fe2.getUniqueName ().equals (partner1)
|
||||
|| fe2.getUniqueName ().equals (partner2))
|
||||
{
|
||||
// System.out.printf ("%s %s%n", name, partner1);
|
||||
((FileEntry) fe2).link ((FileEntry) fe);
|
||||
((FileEntry) fe).link ((FileEntry) fe2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCorrectFormat (AppleDisk disk)
|
||||
|
Loading…
x
Reference in New Issue
Block a user