This commit is contained in:
Denis Molony 2019-08-21 10:31:11 +10:00
parent 6c6adcce08
commit cdde71b158
7 changed files with 396 additions and 200 deletions

View File

@ -0,0 +1,81 @@
package com.bytezone.diskbrowser.applefile;
import java.util.ArrayList;
import java.util.List;
public class AssemblerBlocks
{
public AssemblerBlocks (byte[] buffer, int loadAddress)
{
int ptr = 0;
boolean inCode = true;
int address = loadAddress;
List<Integer> loadTargets = new ArrayList<> ();
List<Integer> branchTargets = new ArrayList<> ();
while (ptr < buffer.length)
{
if (branchTargets.contains (address))
inCode = true;
if (inCode)
{
AssemblerStatement cmd = new AssemblerStatement (buffer[ptr]);
if (cmd.size == 2 && ptr < buffer.length - 1)
cmd.addData (buffer[ptr + 1]);
else if (cmd.size == 3 && ptr < buffer.length - 2)
cmd.addData (buffer[ptr + 1], buffer[ptr + 2]);
else
cmd.size = 1;
cmd.address = address;
if (branchTargets.contains (address))
System.out.print ("> ");
else
System.out.print (" ");
System.out.printf ("%s%n", cmd);
ptr += cmd.size;
address += cmd.size;
// RTS, JMP
if (cmd.opcode == 0x60 || cmd.opcode == 0x4C)
inCode = false;
// JMP, JMP, JSR
// System.out.printf ("%02X %02X %02X%n", cmd.opcode, cmd.operand1, cmd.operand2);
if (cmd.opcode == 0x4C || cmd.opcode == 0x6C || cmd.opcode == 0x20)
{
branchTargets.add (cmd.target);
}
if (cmd.opcode == 0xB9)
{
int target = ((cmd.operand2 & 0xFF) << 8) | (cmd.operand1 & 0xFF);
loadTargets.add (target);
}
// branch relative
if (cmd.offset != 0)
branchTargets.add (cmd.address + cmd.offset + 2);
}
else
{
if (loadTargets.contains (address))
System.out.print ("* ");
else
System.out.print (" ");
System.out.printf ("%06X %02X %s%n", address, buffer[ptr],
(char) (buffer[ptr] & 0x7F));
ptr += 1;
address += 1;
}
}
for (int loadTarget : loadTargets)
System.out.printf ("load : $%04X%n", loadTarget);
for (int branchTarget : branchTargets)
System.out.printf ("branch: $%04X%n", branchTarget);
}
}

View File

@ -8,7 +8,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import com.bytezone.common.Utility;
import com.bytezone.diskbrowser.gui.AssemblerPreferences;
@ -24,8 +23,17 @@ public class AssemblerProgram extends AbstractFile
private byte[] extraBuffer = new byte[0];
// private TreeMap<Integer, String> strings;
private List<Integer> entryPoints;
private List<StringLocation> stringLocations;
static AssemblerPreferences assemblerPreferences;
public static void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
{
AssemblerProgram.assemblerPreferences = assemblerPreferences;
}
public AssemblerProgram (String name, byte[] buffer, int address)
{
super (name, buffer);
@ -33,6 +41,8 @@ public class AssemblerProgram extends AbstractFile
if (equates == null)
getEquates ();
// AssemblerBlocks assemblerBlocks = new AssemblerBlocks (buffer, address);
}
public AssemblerProgram (String name, byte[] buffer, int address, int executeOffset)
@ -41,11 +51,6 @@ public class AssemblerProgram extends AbstractFile
this.executeOffset = executeOffset;
}
public static void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
{
AssemblerProgram.assemblerPreferences = assemblerPreferences;
}
public void setExtraBuffer (byte[] fullBuffer, int offset, int length)
{
if (length >= 0)
@ -114,8 +119,12 @@ public class AssemblerProgram extends AbstractFile
private String getListing ()
{
StringBuilder pgm = new StringBuilder ();
List<AssemblerStatement> lines = getLines ();
if (stringLocations == null)
getStrings ();
// if the assembly doesn't start at the beginning, just dump the bytes that
// are skipped
for (int i = 0; i < executeOffset; i++)
@ -138,6 +147,7 @@ public class AssemblerProgram extends AbstractFile
line.append (" ");
line.append (cmd.mnemonic + " " + cmd.operand);
if (cmd.offset != 0)
{
int branch = cmd.address + cmd.offset + 2;
@ -160,6 +170,7 @@ public class AssemblerProgram extends AbstractFile
break;
}
}
pgm.append (line.toString () + "\n");
}
@ -169,6 +180,20 @@ public class AssemblerProgram extends AbstractFile
return pgm.toString ();
}
// private int showString (AssemblerStatement cmd, StringBuilder line)
// {
// int key = cmd.address - loadAddress;
// if (strings.containsKey (key))
// {
// while (line.length () < 40)
// line.append (" ");
// String s = strings.get (key);
// line.append ("# " + s);
// return s.length () - cmd.size;
// }
// return 0;
// }
private List<AssemblerStatement> getLines ()
{
List<AssemblerStatement> lines = new ArrayList<AssemblerStatement> ();
@ -193,9 +218,12 @@ public class AssemblerProgram extends AbstractFile
else
cmd.size = 1;
// JMP, JMP, JSR
if (cmd.target >= loadAddress && cmd.target < (loadAddress + buffer.length)
&& (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x20))
targets.add (cmd.target);
// branch relative
if (cmd.offset != 0)
targets.add (cmd.address + cmd.offset + 2);
@ -215,18 +243,19 @@ public class AssemblerProgram extends AbstractFile
private String getStringsText ()
{
Map<Integer, String> strings = getStrings ();
if (strings.size () == 0)
if (stringLocations.size () == 0)
return "";
List<Integer> entryPoints = getEntryPoints ();
StringBuilder text = new StringBuilder ("\n\nPossible strings:\n\n");
for (Integer key : strings.keySet ())
for (StringLocation stringLocation : stringLocations)
{
String s = strings.get (key);
int start = key + loadAddress;
text.append (String.format ("%s %04X - %04X %s %n",
entryPoints.contains (start) ? "*" : " ", start, start + s.length (), s));
if (stringLocation.zeroTerminated)
text.append (String.format ("%s %04X - %04X %s %s %n",
entryPoints.contains (stringLocation.offset + loadAddress) ? "*" : " ",
stringLocation.offset, stringLocation.offset + stringLocation.length,
stringLocation.toStatisticsString (), stringLocation));
else
System.out.println (stringLocation);
}
if (text.length () > 0)
@ -235,31 +264,17 @@ public class AssemblerProgram extends AbstractFile
return text.toString ();
}
private Map<Integer, String> getStrings ()
private void getStrings ()
{
TreeMap<Integer, String> strings = new TreeMap<> ();
entryPoints = new ArrayList<> ();
stringLocations = new ArrayList<> ();
int start = 0;
for (int ptr = 0; ptr < buffer.length; ptr++)
{
if ((buffer[ptr] & 0x80) != 0) // high bit set
continue;
if (buffer[ptr] == 0 // possible end of string
&& ptr - start > 5)
strings.put (start, HexFormatter.getString (buffer, start, ptr - start));
start = ptr + 1;
}
return strings;
}
private List<Integer> getEntryPoints ()
{
List<Integer> entryPoints = new ArrayList<> ();
for (int ptr = 0; ptr < buffer.length; ptr++)
if ((buffer[ptr] == (byte) 0xBD || buffer[ptr] == (byte) 0xB9)
if ((buffer[ptr] == (byte) 0xBD // LDA Absolute,X
|| buffer[ptr] == (byte) 0xB9 // LDA Absolute,Y
|| buffer[ptr] == (byte) 0xAD) // LDA Absolute
&& (ptr + 2 < buffer.length))
{
int address = Utility.getWord (buffer, ptr + 1);
@ -267,7 +282,17 @@ public class AssemblerProgram extends AbstractFile
entryPoints.add (address);
}
return entryPoints;
if ((buffer[ptr] & 0x80) != 0) // hi bit set
continue;
if (ptr - start > 3)
stringLocations.add (new StringLocation (start, ptr - 1));
start = ptr + 1;
}
if (buffer.length - start > 3)
stringLocations.add (new StringLocation (start, buffer.length - 1));
}
private String getArrow (AssemblerStatement cmd)
@ -324,4 +349,78 @@ public class AssemblerProgram extends AbstractFile
e.printStackTrace ();
}
}
class StringLocation
{
int offset;
int length;
boolean zeroTerminated;
boolean hasLengthByte;
int digits;
int letters;
int punctuation;
int controlChars;
int spaces;
public StringLocation (int first, int last)
{
offset = first;
length = last - offset + 1;
zeroTerminated = ++last < buffer.length && buffer[last] == 0;
hasLengthByte = first > 0 && (buffer[first] & 0xFF) == length;
for (int i = offset; i < offset + length; i++)
{
int val = buffer[i] & 0x7F;
if (val < 32 || val == 127)
++controlChars;
else if (val == 32)
++spaces;
else if (val >= 48 && val <= 57)
++digits;
else if (val >= 65 && val <= 90)
++letters;
else if (val >= 97 && val <= 122)
++letters;
else
++punctuation;
}
}
boolean likelyString ()
{
return spaces > 0 || letters > punctuation;
}
public String toStatisticsString ()
{
return String.format ("%2d, %2d, %2d, %2d, %2d", digits, letters, punctuation,
controlChars, spaces);
}
@Override
public String toString ()
{
StringBuilder text = new StringBuilder ();
if (hasLengthByte)
text.append ("<length>");
for (int i = offset; i < offset + length; i++)
{
int val = buffer[i] & 0x7F;
if (val == 4)
text.append ("<ctrl-D>");
else if (val == 10)
text.append ("<LF>");
else if (val == 13)
text.append ("<CR>");
else
text.append ((char) val);
}
return text.toString ();
}
}
}

View File

@ -19,7 +19,6 @@ public class AssemblerStatement
public int address;
public boolean isTarget;
public byte operand1, operand2;
String ascii = "";
public static void print ()
{
@ -74,7 +73,6 @@ public class AssemblerStatement
this.mnemonic = AssemblerConstants.mnemonics[this.opcode];
this.size = AssemblerConstants.sizes2[this.opcode];
this.operand = "";
ascii = getChar (opcode);
}
String getChar (byte val)
@ -95,7 +93,7 @@ public class AssemblerStatement
public void addData ()
{
switch (this.opcode)
switch (opcode)
{
case 0x00: // BRK
case 0x08: // PHP
@ -147,119 +145,116 @@ public class AssemblerStatement
{
operand1 = b;
String address = "$" + HexFormatter.format2 (b);
// if (this.mnemonic.equals ("JSR"))
// this.target = HexFormatter.intValue (b);
ascii += getChar (b);
switch (this.opcode)
{
case 0x09: // ORA
case 0x29: // AND
case 0x49: // EOR
case 0x69: // ADC
case 0x89: // NOP - 65c02
case 0xA0: // LDY
case 0xA2: // LDX
case 0xA9: // LDA
case 0xC0: // CPY
case 0xC9: // CMP
case 0xE0: // CPX
case 0xE9: // SBC
case 0x09: // ORA
case 0x29: // AND
case 0x49: // EOR
case 0x69: // ADC
case 0x89: // NOP - 65c02
case 0xA0: // LDY
case 0xA2: // LDX
case 0xA9: // LDA
case 0xC0: // CPY
case 0xC9: // CMP
case 0xE0: // CPX
case 0xE9: // SBC
operand = "#" + address;
mode = 2; // Immediate
mode = 2; // Immediate
break;
case 0x04: // NOP - 65c02
case 0x05: // ORA
case 0x06: // ASL
case 0x14: // NOP - 65c02
case 0x24: // BIT
case 0x25: // AND
case 0x26: // ROL
case 0x45: // EOR
case 0x46: // LSR
case 0x64: // NOP - 65c02
case 0x65: // ADC
case 0x66: // ROR
case 0x84: // STY
case 0x85: // STA
case 0x86: // STX
case 0xA4: // LDY
case 0xA5: // LDA
case 0xA6: // LDX
case 0xC4: // CPY
case 0xC5: // CMP
case 0xC6: // DEC
case 0xE4: // CPX
case 0xE5: // SBC
case 0xE6: // INC
case 0x04: // NOP - 65c02
case 0x05: // ORA
case 0x06: // ASL
case 0x14: // NOP - 65c02
case 0x24: // BIT
case 0x25: // AND
case 0x26: // ROL
case 0x45: // EOR
case 0x46: // LSR
case 0x64: // NOP - 65c02
case 0x65: // ADC
case 0x66: // ROR
case 0x84: // STY
case 0x85: // STA
case 0x86: // STX
case 0xA4: // LDY
case 0xA5: // LDA
case 0xA6: // LDX
case 0xC4: // CPY
case 0xC5: // CMP
case 0xC6: // DEC
case 0xE4: // CPX
case 0xE5: // SBC
case 0xE6: // INC
target = b & 0xFF;
operand = address;
mode = 8; // Zero page
mode = 8; // Zero page
break;
case 0x15: // ORA
case 0x16: // ASL
case 0x34: // NOP - 65c02
case 0x35: // AND
case 0x36: // ROL
case 0x55: // EOR
case 0x56: // LSR
case 0x74: // NOP - 65c02
case 0x75: // ADC
case 0x76: // ROR
case 0x94: // STY
case 0x95: // STA
case 0xB4: // LDY
case 0xB5: // LDA
case 0xD5: // CMP
case 0xD6: // DEC
case 0xF5: // SBC
case 0xF6: // INC
case 0x15: // ORA
case 0x16: // ASL
case 0x34: // NOP - 65c02
case 0x35: // AND
case 0x36: // ROL
case 0x55: // EOR
case 0x56: // LSR
case 0x74: // NOP - 65c02
case 0x75: // ADC
case 0x76: // ROR
case 0x94: // STY
case 0x95: // STA
case 0xB4: // LDY
case 0xB5: // LDA
case 0xD5: // CMP
case 0xD6: // DEC
case 0xF5: // SBC
case 0xF6: // INC
operand = address + ",X";
mode = 9; // Zero page, X
mode = 9; // Zero page, X
break;
case 0x96: // STX
case 0xB6: // LDX
case 0x96: // STX
case 0xB6: // LDX
operand = address + ",Y";
mode = 10; // Zero page, Y
mode = 10; // Zero page, Y
break;
case 0x01: // ORA
case 0x21: // AND
case 0x41: // EOR
case 0x61: // ADC
case 0x81: // STA
case 0xA1: // LDA
case 0xC1: // CMP
case 0xE1: // SEC
case 0x01: // ORA
case 0x21: // AND
case 0x41: // EOR
case 0x61: // ADC
case 0x81: // STA
case 0xA1: // LDA
case 0xC1: // CMP
case 0xE1: // SEC
operand = "(" + address + ",X)";
mode = 11; // (Indirect, X)
mode = 11; // (Indirect, X)
break;
case 0x11: // ORA
case 0x31: // AND
case 0x51: // EOR
case 0x71: // ADC
case 0x91: // STA
case 0xB1: // LDA
case 0xD1: // CMP
case 0xF1: // SBC
case 0x11: // ORA
case 0x31: // AND
case 0x51: // EOR
case 0x71: // ADC
case 0x91: // STA
case 0xB1: // LDA
case 0xD1: // CMP
case 0xF1: // SBC
operand = "(" + address + "),Y";
mode = 12; // (Indirect), Y
mode = 12; // (Indirect), Y
break;
case 0x12: // NOP
case 0x32: // NOP
case 0x52: // NOP
case 0x72: // NOP
case 0x92: // NOP
case 0xB2: // NOP
case 0xD2: // NOP
case 0xF2: // NOP
operand = "(" + address + ")"; // all 65c02
mode = 13; // (zero page)
case 0x12: // NOP
case 0x32: // NOP
case 0x52: // NOP
case 0x72: // NOP
case 0x92: // NOP
case 0xB2: // NOP
case 0xD2: // NOP
case 0xF2: // NOP
operand = "(" + address + ")"; // all 65c02
mode = 13; // (zero page)
break;
case 0x10: // BPL
@ -272,7 +267,7 @@ public class AssemblerStatement
case 0xD0: // BNE
case 0xF0: // BEQ
offset = b;
mode = 14; // relative
mode = 14; // relative
this.target = b & 0xFF;
break;
@ -286,11 +281,6 @@ public class AssemblerStatement
operand1 = b1;
operand2 = b2;
String address = "$" + HexFormatter.format2 (b2) + HexFormatter.format2 (b1);
// if (this.mnemonic.equals ("JSR") || this.mnemonic.equals ("JMP")
// || this.mnemonic.equals ("BIT") || this.mnemonic.equals ("STA")
// || this.mnemonic.equals ("LDA"))
// this.target = HexFormatter.intValue (b1, b2);
ascii += getChar (b1) + getChar (b2);
switch (this.opcode)
{
@ -378,8 +368,11 @@ public class AssemblerStatement
public String toString ()
{
if (offset == 0)
return String.format ("%d %3s %-10s %02X", size, mnemonic, operand, value);
return String.format ("%d %3s %-10s %02X", size, mnemonic, operand + "+" + offset,
value);
return String.format ("%06X %d %3s %-10s %02X", address, size, mnemonic, operand,
value);
String offsetText = String.format ("$%04X", address + offset + 2);
return String.format ("%06X %d %3s %-10s %02X", address, size, mnemonic,
operand + offsetText, value);
}
}

View File

@ -38,7 +38,7 @@ public abstract class HiResImage extends AbstractFile
// $C0 PNT $0003 Packed IIGS QuickDraw II PICT File - SHRPictureFile2 *
// * $C0 PNT $0004 Packed Super Hi-Res 3200 (Brooks) .3201 - SHRPictureFile2
// $C0 PNT $1000
// $C0 PNT $8000 Drawplus ?
// $C0 PNT $8000 Drawplus? Paintworks Gold?
// $C0 PNT $8001 GTv background picture
// $C0 PNT $8005 DreamGraphix document
// $C0 PNT $8006 GIF
@ -315,45 +315,11 @@ public abstract class HiResImage extends AbstractFile
return newBuf;
}
private int calculateBufferSize (byte[] buffer)
{
int ptr = 0;
int size = 0;
while (ptr < buffer.length)
{
int type = (buffer[ptr] & 0xC0) >> 6; // 0-3
int count = (buffer[ptr++] & 0x3F) + 1; // 1-64
if (type == 0)
{
ptr += count;
size += count;
}
else if (type == 1)
{
ptr++;
size += count;
}
else if (type == 2)
{
ptr += 4;
size += count * 4;
}
else
{
ptr++;
size += count * 4;
}
}
return size;
}
// Super Hi-res IIGS (MAIN in $C0/02)
int unpackLine (byte[] buffer, byte[] newBuf, int newPtr)
{
byte[] fourBuf = new byte[4];
int oldPtr = newPtr;
int ptr = 0;
while (ptr < buffer.length)
{
@ -397,11 +363,43 @@ public abstract class HiResImage extends AbstractFile
break;
}
}
// System.out.println (HexFormatter.format (newBuf, oldPtr, newPtr - oldPtr));
return newPtr;
}
private int calculateBufferSize (byte[] buffer)
{
int ptr = 0;
int size = 0;
while (ptr < buffer.length)
{
int type = (buffer[ptr] & 0xC0) >> 6; // 0-3
int count = (buffer[ptr++] & 0x3F) + 1; // 1-64
if (type == 0)
{
ptr += count;
size += count;
}
else if (type == 1)
{
ptr++;
size += count;
}
else if (type == 2)
{
ptr += 4;
size += count * 4;
}
else
{
ptr++;
size += count * 4;
}
}
return size;
}
// Beagle Bros routine to expand a hi-res screen
private byte[] unscrunch (byte[] src)
{

View File

@ -12,23 +12,24 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class IconFile extends AbstractFile
{
private static Palette palette = new Palette ("Virtual II", new int[] { 0x000000, // 0 black
0xDD0033, // 1 magenta
0x885500, // 2 brown (8)
0xFF6600, // 3 orange (9)
0x007722, // 4 dark green
0x555555, // 5 grey1
0x11DD00, // 6 light green (C)
0xFFFF00, // 7 yellow (D)
0x000099, // 8 dark blue (2)
0xDD22DD, // 9 purple (3)
0xAAAAAA, // A grey2
0xFF9988, // B pink
0x2222FF, // C med blue (6)
0x66AAFF, // D light blue (7)
0x44FF99, // E aqua
0xFFFFFF // F white
});
private static Palette palette = //
new Palette ("Virtual II", new int[] { 0x000000, // 0 black
0xDD0033, // 1 magenta
0x885500, // 2 brown (8)
0xFF6600, // 3 orange (9)
0x007722, // 4 dark green
0x555555, // 5 grey1
0x11DD00, // 6 light green (C)
0xFFFF00, // 7 yellow (D)
0x000099, // 8 dark blue (2)
0xDD22DD, // 9 purple (3)
0xAAAAAA, // A grey2
0xFF9988, // B pink
0x2222FF, // C med blue (6)
0x66AAFF, // D light blue (7)
0x44FF99, // E aqua
0xFFFFFF // F white
});
// private static Palette palette = new Palette ("Icon palette",
// new int[] { 0x000000, // 0 black
// 0x2222FF, // C med blue (6)
@ -69,7 +70,8 @@ public class IconFile extends AbstractFile
int dataLen = HexFormatter.unsignedShort (buffer, ptr);
if (dataLen == 0 || (dataLen + ptr) > buffer.length)
break;
icons.add (new Icon (buffer, ptr));
Icon icon = new Icon (buffer, ptr);
icons.add (icon);
ptr += dataLen;
}
@ -165,8 +167,15 @@ public class IconFile extends AbstractFile
iDataType = HexFormatter.unsignedShort (buffer, 82);
iDataAux = HexFormatter.unsignedShort (buffer, 84);
largeImage = new Image (buffer, 86);
smallImage = new Image (buffer, 86 + largeImage.size ());
try
{
largeImage = new Image (buffer, 86);
smallImage = new Image (buffer, 86 + largeImage.size ());
}
catch (InvalidImageException e)
{
System.out.println (e.getMessage ());
}
}
@Override
@ -196,18 +205,27 @@ public class IconFile extends AbstractFile
boolean colour;
private final BufferedImage image;
public Image (byte[] buffer, int ptr)
public Image (byte[] buffer, int ptr) throws InvalidImageException
{
iconType = HexFormatter.unsignedShort (buffer, ptr);
iconSize = HexFormatter.unsignedShort (buffer, ptr + 2);
iconHeight = HexFormatter.unsignedShort (buffer, ptr + 4);
iconWidth = HexFormatter.unsignedShort (buffer, ptr + 6);
if (iconType != 0 && iconType != 0x8000)
throw new InvalidImageException (String.format ("Bad icon type: %04X", iconType));
iconImage = new byte[iconSize];
iconMask = new byte[iconSize];
colour = (iconType & 0x80) != 0;
// System.out.printf ("Icon type %04X %<d%n", iconType);
// System.out.printf ("Icon size %d%n", iconSize);
// System.out.printf ("Icon height %d%n", iconHeight);
// System.out.printf ("Icon width %d%n", iconWidth);
// System.out.println ();
System.arraycopy (buffer, ptr + 8, iconImage, 0, iconSize);
System.arraycopy (buffer, ptr + 8 + iconSize, iconMask, 0, iconSize);
@ -277,7 +295,7 @@ public class IconFile extends AbstractFile
5 Red D00 1
6 Green 0E0 2
7 White FFF 3
8 Black 000 0
9 Blue 00F 1
10 Yellow FF0 2
@ -286,7 +304,7 @@ public class IconFile extends AbstractFile
13 Red D00 1
14 Green 0E0 2
15 White FFF 3
The displayMode word bits are defined as:
Bit 0 selectedIconBit 1 = invert image before copying
@ -320,4 +338,12 @@ public class IconFile extends AbstractFile
text.deleteCharAt (text.length () - 1);
}
}
class InvalidImageException extends Exception
{
public InvalidImageException (String message)
{
super (message);
}
}
}

View File

@ -310,14 +310,12 @@ public class SHRPictureFile1 extends HiResImage
ptr = 0;
for (int line = 0; line < numScanLines; line++)
{
// byte[] lineBuffer = packedScanLines[line];
if (isOddAndEmpty (packedScanLines[line]))
{
System.out.println ("Odd number of bytes in empty buffer in " + name);
break;
}
// System.out.printf ("Line: %3d%n", line);
// System.out.println (scanLineDirectory[line]);
ptr = unpackLine (packedScanLines[line], unpackedBuffer, ptr);
// something strange happening here

View File

@ -40,6 +40,7 @@ public class SHRPictureFile2 extends HiResImage
switch (auxType)
{
case 0: // packed Paintworks SHR
case 0x8000: // Paintworks Gold
controlBytes = new byte[200]; // all pointing to 0th color table
colorTables = new ColorTable[1];
colorTables[0] = new ColorTable (0, this.buffer, 0);