Compare commits
156 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dafc29c60e | ||
|
706c64435f | ||
|
2bc330e377 | ||
|
6c81bcc93b | ||
|
171fd66ba1 | ||
|
aa77ec1cd4 | ||
|
8f95988596 | ||
|
8cb682f068 | ||
|
dfc7a68580 | ||
|
4b476457d3 | ||
|
3bf972a761 | ||
|
fd5bee6e5c | ||
|
0af6714119 | ||
|
22dfaf65c6 | ||
|
f4a6465b04 | ||
|
64d5ce9ee2 | ||
|
4e48437adc | ||
|
e2abdcabc9 | ||
|
bc0993e9d3 | ||
|
9fba3893ba | ||
|
09c4542118 | ||
|
af3ead0441 | ||
|
c12392200b | ||
|
794fef8610 | ||
|
2ec0e10c5e | ||
|
668ed719fa | ||
|
23b95675cf | ||
|
b98ecbed8d | ||
|
82381a6a47 | ||
|
3f2f1bfbca | ||
|
a7119528a6 | ||
|
6f943ae8c2 | ||
|
5add6c0729 | ||
|
921c946ab5 | ||
|
898587b23b | ||
|
37c489f252 | ||
|
036e47b9b1 | ||
|
250c1a9bd9 | ||
|
b19e89d7cf | ||
|
d71cabb754 | ||
|
848b2469ae | ||
|
989b1d5ab9 | ||
|
e0a2c50d5b | ||
|
8765299cf4 | ||
|
97fe58d94d | ||
|
7d4d8c75e6 | ||
|
f5664a9ce9 | ||
|
9d8cdcd67b | ||
|
12b74f9d21 | ||
|
1b405c6f38 | ||
|
66d6910f91 | ||
|
572ee8c3a1 | ||
|
2a14b7baad | ||
|
a633e28ed3 | ||
|
ca11e8ee68 | ||
|
ce52253f5d | ||
|
e408aa3d62 | ||
|
c4b4d17f52 | ||
|
0b72f1a37d | ||
|
1b86b31233 | ||
|
1b9e9d47ac | ||
|
decc781572 | ||
|
16ccc2632a | ||
|
40c2afbd48 | ||
|
f9038810d2 | ||
|
3435e825df | ||
|
ff7c6fd126 | ||
|
91846d8563 | ||
|
19b6339ac5 | ||
|
db4953618c | ||
|
c1deee56a0 | ||
|
b1ed1a74ba | ||
|
cf0cfd278b | ||
|
48aca6e1eb | ||
|
d83ac3afda | ||
|
2270b1f6db | ||
|
da67dbe0d7 | ||
|
133352ba31 | ||
|
761c43dc3d | ||
|
d03de97247 | ||
|
e67bbeaf8b | ||
|
6dfc72b2d2 | ||
|
fb748df4ae | ||
|
4a03c411fc | ||
|
54db7d95d6 | ||
|
59b22be2bd | ||
|
47a07f5cfe | ||
|
bca12f0738 | ||
|
27100ad38e | ||
|
2a6fd74013 | ||
|
4767c317d0 | ||
|
068f382c87 | ||
|
e7d8c4ebc2 | ||
|
9ef0f82dea | ||
|
fba8c07142 | ||
|
4aefc8b695 | ||
|
a8574d24f8 | ||
|
449e6c0e9a | ||
|
09b6f66855 | ||
|
f30fe1a78a | ||
|
0e40e25710 | ||
|
f02c932d91 | ||
|
c18cfe9ed7 | ||
|
dcb3e32845 | ||
|
08d6d1b136 | ||
|
954b0c0bd8 | ||
|
f22b4dcd46 | ||
|
c42481637e | ||
|
7ca8160d13 | ||
|
26316a82a9 | ||
|
5f29cfcd09 | ||
|
7f2e963689 | ||
|
8ea18c8cc1 | ||
|
f92fe5b57e | ||
|
bb4dcbdd7c | ||
|
8aec65449e | ||
|
ff273e7df9 | ||
|
1a1f9df93f | ||
|
80a07c0496 | ||
|
8369e4a788 | ||
|
bfeab1477c | ||
|
ad8464c6c2 | ||
|
b1ff2f7740 | ||
|
4040238bbf | ||
|
70f21070d5 | ||
|
91693bbc37 | ||
|
8a9b824302 | ||
|
06f4713baa | ||
|
e7ded68b03 | ||
|
58cec66535 | ||
|
c105d07e60 | ||
|
3e32b3caf0 | ||
|
7aa80b8b5e | ||
|
5e053872a9 | ||
|
7d162a4baf | ||
|
83d5be3f9f | ||
|
ea0a827331 | ||
|
dc551285bb | ||
|
95538f5282 | ||
|
9d706d62ef | ||
|
63fc59accc | ||
|
beb0830c25 | ||
|
ae1188ae27 | ||
|
1b27ea02e7 | ||
|
c2f2277717 | ||
|
79ccd6793c | ||
|
5be0236845 | ||
|
59bf768d14 | ||
|
566479450a | ||
|
b45e7d7e54 | ||
|
9dddd2be3e | ||
|
d3f21e0d49 | ||
|
af706e03c7 | ||
|
b6496e9c87 | ||
|
a33aedd750 | ||
|
13647213c6 |
4
.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
/bin/
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
build.xml
|
|
17
README.md
@ -1,5 +1,6 @@
|
|||||||
# Apple II Disk Browser
|
# Apple II Disk Browser
|
||||||
|
### Alternative
|
||||||
|
There is a new release of [DiskBrowser2](https://github.com/dmolony/diskbrowser2) available.
|
||||||
### Features
|
### Features
|
||||||
- Cross-platform (Windows, MacOS, Linux)
|
- Cross-platform (Windows, MacOS, Linux)
|
||||||
- Disk formats
|
- Disk formats
|
||||||
@ -30,7 +31,7 @@
|
|||||||
* [Usage](resources/usage.md)
|
* [Usage](resources/usage.md)
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
* Install the **latest** version of the [JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html).
|
* Install the **latest** version of the [JDK](https://www.oracle.com/java/technologies/downloads/).
|
||||||
* Download DiskBrowser.jar from the [releases](https://github.com/dmolony/diskbrowser/releases) page.
|
* Download DiskBrowser.jar from the [releases](https://github.com/dmolony/diskbrowser/releases) page.
|
||||||
* Double-click the jar file, or enter 'java -jar DiskBrowser.jar' in the terminal.
|
* Double-click the jar file, or enter 'java -jar DiskBrowser.jar' in the terminal.
|
||||||
* Set your root folder (the top-level folder where you keep your disk images).
|
* Set your root folder (the top-level folder where you keep your disk images).
|
||||||
@ -52,14 +53,24 @@ Java runs on Windows, MacOS and Linux.
|
|||||||
#### Graphics
|
#### Graphics
|
||||||
![Graphics](resources/graphics.png?raw=true "Graphics")
|
![Graphics](resources/graphics.png?raw=true "Graphics")
|
||||||
#### Applesoft Formatting and Analysis
|
#### Applesoft Formatting and Analysis
|
||||||
|
Applesoft programs are displayed in a modern, easily-readable format. A comprehensive cross-listing of variables, strings, calls and jumps is available. Easily find duplicate variable names.
|
||||||
|
For the truly retro look, programs can be displayed in the [original 40-column line wrap](resources/basic.md) mode.
|
||||||
![Applesoft](resources/basic.png?raw=true "Applesoft")
|
![Applesoft](resources/basic.png?raw=true "Applesoft")
|
||||||
#### Pascal code
|
#### Pascal code
|
||||||
![Pascal](resources/pascal.png?raw=true "Pascal")
|
![Pascal](resources/pascal1.png?raw=true "Pascal text")
|
||||||
|
![Pascal](resources/pascal2.png?raw=true "Pascal internals")
|
||||||
#### Infocom
|
#### Infocom
|
||||||
![Infocom](resources/zork.png?raw=true "Infocom")
|
![Infocom](resources/zork.png?raw=true "Infocom")
|
||||||
#### Wizardry
|
#### Wizardry
|
||||||
|
Wizardry scenarios 1 to 3 are reasonably complete, Wizardry IV and V are partially done. For a dedicated Wizardry application see [WizardryApp](https://github.com/dmolony/WizardryApp).
|
||||||
![Wizardry](resources/wizardry.png?raw=true "Wizardry")
|
![Wizardry](resources/wizardry.png?raw=true "Wizardry")
|
||||||
|
Scenarios 4 and 5 come on multiple disks, and they need to be named so that the only difference between disk names is the identifier before the '.dsk' suffix.
|
||||||
|
![Wizardry](resources/wizardry4.png?raw=true "Wizardry IV")
|
||||||
#### Visicalc
|
#### Visicalc
|
||||||
|
DiskBrowser has an inbuilt Visicalc processor which will evaluate the sheet and display the results.
|
||||||
![Visicalc](resources/visicalc.png?raw=true "Visicalc")
|
![Visicalc](resources/visicalc.png?raw=true "Visicalc")
|
||||||
#### Complete Disk List
|
#### Complete Disk List
|
||||||
|
Generates a list of all the disks in your collection. The list can be sorted by any of the table headings. Checksums can be generated as needed, or for the whole collection.
|
||||||
![Disk List](resources/disklist.png?raw=true "Disk List")
|
![Disk List](resources/disklist.png?raw=true "Disk List")
|
||||||
|
Select a disk and click the duplicates button to see all of the disks that share the same checksum.
|
||||||
|
![Duplicates](resources/duplicates.png?raw=true "Duplicates")
|
||||||
|
40
build.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<project name="DiskBrowser" default="jar" basedir=".">
|
||||||
|
|
||||||
|
<property name="srcDir" location="src" />
|
||||||
|
<property name="binDir" location="bin" />
|
||||||
|
<property name="jarDir" location="${user.home}/Dropbox/Java" />
|
||||||
|
<property name="jarFile" location="${jarDir}/DiskBrowser.jar" />
|
||||||
|
|
||||||
|
<target name="version">
|
||||||
|
<echo>DiskBrowser.jar</echo>
|
||||||
|
<echo>${ant.version}</echo>
|
||||||
|
<echo>Java/JVM version: ${ant.java.version}</echo>
|
||||||
|
<echo>Java/JVM detail version: ${java.version}</echo>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="init" depends="version">
|
||||||
|
<delete file="${binDir}/*.class" />
|
||||||
|
<delete file="${jarFile}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="compile" depends="init">
|
||||||
|
<javac debug="on" srcdir="${srcDir}" destdir="${binDir}" includeantruntime="false">
|
||||||
|
<classpath>
|
||||||
|
<pathelement location="." />
|
||||||
|
</classpath>
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar" depends="compile">
|
||||||
|
<jar destfile="${jarFile}">
|
||||||
|
<fileset dir="${binDir}" />
|
||||||
|
<zipfileset src="${jarDir}/InputPanel.jar" />
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Main-Class" value="com.bytezone.diskbrowser.gui.DiskBrowser" />
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</project>
|
13
resources/basic.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
### Applesoft program listing
|
||||||
|
|
||||||
|
#### State of the art circa 1980
|
||||||
|
<img src="basic0.png" alt="terrible" width="700"/>
|
||||||
|
|
||||||
|
#### Original (using Print Char 21)
|
||||||
|
<img src="basic5.png" alt="truly awful" width="400"/>
|
||||||
|
|
||||||
|
#### No formatting
|
||||||
|
<img src="basic2.png" alt="better" width="850"/>
|
||||||
|
|
||||||
|
#### Formatted
|
||||||
|
<img src="basic3.png" alt="best" width="550"/>
|
BIN
resources/basic0.png
Normal file
After Width: | Height: | Size: 730 KiB |
BIN
resources/basic1.png
Normal file
After Width: | Height: | Size: 101 KiB |
BIN
resources/basic2.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
resources/basic3.png
Normal file
After Width: | Height: | Size: 128 KiB |
BIN
resources/basic4.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
resources/basic5.png
Normal file
After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 784 KiB After Width: | Height: | Size: 1.1 MiB |
BIN
resources/duplicates.png
Normal file
After Width: | Height: | Size: 373 KiB |
Before Width: | Height: | Size: 788 KiB |
BIN
resources/pascal1.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
resources/pascal2.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 642 KiB After Width: | Height: | Size: 1.0 MiB |
BIN
resources/wizardry4.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
@ -17,9 +17,9 @@ public abstract class AbstractFile implements DataSource
|
|||||||
|
|
||||||
protected String name;
|
protected String name;
|
||||||
public byte[] buffer;
|
public byte[] buffer;
|
||||||
protected AssemblerProgram assembler;
|
AssemblerProgram assembler;
|
||||||
protected BufferedImage image;
|
protected BufferedImage image;
|
||||||
protected int loadAddress;
|
int loadAddress;
|
||||||
ResourceFork resourceFork;
|
ResourceFork resourceFork;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -30,12 +30,29 @@ public abstract class AbstractFile implements DataSource
|
|||||||
this.buffer = buffer;
|
this.buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void setName (String name)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
this.name = name; // Infocom ZObject uses this - but it sucks
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public String getText () // Override this to get a tailored text representation
|
public String getText () // Override this to get a tailored text representation
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return "Name : " + name + "\n\nNo text description";
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
|
text.append ("Name : " + name + "\n\nNo text description");
|
||||||
|
|
||||||
|
if (resourceFork != null)
|
||||||
|
{
|
||||||
|
text.append ("\n\nResource Fork:\n\n");
|
||||||
|
text.append (resourceFork);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text.toString ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -10,7 +10,7 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons
|
|||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final List<SourceLine> sourceLines = new ArrayList<> ();
|
private final List<SourceLine> sourceLines = new ArrayList<> ();
|
||||||
private int ptr; // end-of-program marker
|
private int ptr = 0; // end-of-program marker
|
||||||
|
|
||||||
private final UserBasicFormatter userBasicFormatter;
|
private final UserBasicFormatter userBasicFormatter;
|
||||||
private final AppleBasicFormatter appleBasicFormatter;
|
private final AppleBasicFormatter appleBasicFormatter;
|
||||||
@ -78,13 +78,6 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons
|
|||||||
return sourceLines;
|
return sourceLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
// byte[] getBuffer ()
|
|
||||||
// // ---------------------------------------------------------------------------------//
|
|
||||||
// {
|
|
||||||
// return buffer;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
int getEndPtr ()
|
int getEndPtr ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -8,8 +8,8 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
|
|||||||
public class BasicTextFile extends TextFile
|
public class BasicTextFile extends TextFile
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static String underline = "------------------------------------------"
|
private static String underline =
|
||||||
+ "------------------------------------\n";
|
"------------------------------------------" + "------------------------------------\n";
|
||||||
private static String fullUnderline = "---------- ------- " + underline;
|
private static String fullUnderline = "---------- ------- " + underline;
|
||||||
private int recordLength; // prodos aux
|
private int recordLength; // prodos aux
|
||||||
private List<TextBuffer> buffers; // only used if it is a Prodos text file
|
private List<TextBuffer> buffers; // only used if it is a Prodos text file
|
||||||
@ -30,6 +30,7 @@ public class BasicTextFile extends TextFile
|
|||||||
super (name, buffer);
|
super (name, buffer);
|
||||||
|
|
||||||
this.eof = eof;
|
this.eof = eof;
|
||||||
|
|
||||||
recordLength = auxType;
|
recordLength = auxType;
|
||||||
prodosFile = true;
|
prodosFile = true;
|
||||||
}
|
}
|
||||||
@ -42,6 +43,7 @@ public class BasicTextFile extends TextFile
|
|||||||
|
|
||||||
this.buffers = buffers;
|
this.buffers = buffers;
|
||||||
this.eof = eof;
|
this.eof = eof;
|
||||||
|
|
||||||
recordLength = auxType;
|
recordLength = auxType;
|
||||||
prodosFile = true;
|
prodosFile = true;
|
||||||
}
|
}
|
||||||
@ -167,8 +169,7 @@ public class BasicTextFile extends TextFile
|
|||||||
if (textPreferences.showTextOffsets)
|
if (textPreferences.showTextOffsets)
|
||||||
{
|
{
|
||||||
line = line.replaceAll ("\\n", "\n ");
|
line = line.replaceAll ("\\n", "\n ");
|
||||||
text.append (
|
text.append (String.format ("%,10d %,8d %s%n", recNo * recordLength, recNo, line));
|
||||||
String.format ("%,10d %,8d %s%n", recNo * recordLength, recNo, line));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
text.append (String.format ("%s%n", line));
|
text.append (String.format ("%s%n", line));
|
||||||
|
229
src/com/bytezone/diskbrowser/applefile/CPMBasicFile.java
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
package com.bytezone.diskbrowser.applefile;
|
||||||
|
|
||||||
|
import static com.bytezone.diskbrowser.utilities.Utility.getShort;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
public class CPMBasicFile extends BasicProgram
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
String[] tokens = { //
|
||||||
|
"", "END", "FOR", "NEXT", "DATA", "INPUT", "DIM", "READ", // 0x80
|
||||||
|
"LET", "GOTO", "RUN", "IF", "RESTORE", "GOSUB", "RETURN", "REM", // 0x88
|
||||||
|
"STOP", "PRINT", "CLEAR", "LIST", "NEW", "ON", "DEF", "POKE", // 0x90
|
||||||
|
"", "", "", "LPRINT", "LLIST", "WIDTH", "ELSE", "", // 0x98
|
||||||
|
"", "SWAP", "ERASE", "", "ERROR", "RESUME", "DELETE", "", // 0xA0
|
||||||
|
"RENUM", "DEFSTR", "DEFINT", "", "DEFDBL", "LINE", "", "WHILE", // 0xA8
|
||||||
|
"WEND", "CALL", "WRITE", "COMMON", "CHAIN", // 0xB0
|
||||||
|
"OPTION", "RANDOMIZE", "SYSTEM", // 0xB5
|
||||||
|
"OPEN", "FIELD", "GET", "PUT", "CLOSE", "LOAD", "MERGE", "", // 0xB8
|
||||||
|
"NAME", "KILL", "LSET", "RSET", "SAVE", "RESET", "TEXT", "HOME", // 0xC0
|
||||||
|
"VTAB", "HTAB", "INVERSE", "NORMAL", "", "", "", "", // 0xC8
|
||||||
|
"", "", "", "", "", "WAIT", "", "", // 0xD0
|
||||||
|
"", "", "", "", "", "TO", "THEN", "TAB(", // 0xD8
|
||||||
|
"STEP", "USR", "FN", "SPC(", "", "ERL", "ERR", "STRING$", // 0xE0
|
||||||
|
"USING", "INSTR", "'", "VARPTR", "", "", "INKEY$", ">", // 0xE8
|
||||||
|
"=", "<", "+", "-", "*", "/", "", "AND", // 0xF0
|
||||||
|
"OR", "", "", "", "MOD", "/", "", "", // 0xF8
|
||||||
|
};
|
||||||
|
|
||||||
|
String[] functions = { //
|
||||||
|
"", "LEFT$", "RIGHT$", "MID$", "SGN", "INT", "ABS", "SQR", // 0x80
|
||||||
|
"RND", "SIN", "LOG", "EXP", "COS", "TAN", "ATN", "FRE", // 0x88
|
||||||
|
"POS", "LEN", "STR$", "VAL", "ASC", "CHR$", "PEEK", "SPACE$", // 0x90
|
||||||
|
"OCT$", "HEX$", "LPOS", "CINT", "CSNG", "CDBL", "FIX", "", // 0x98
|
||||||
|
"", "", "", "", "", "", "", "", // 0xA0
|
||||||
|
"", "", "CVI", "CVS", "CVD", "", "EOF", "LOC", // 0xA8
|
||||||
|
"", "MKI$", "MKS$", "MKD$", // 0xB0
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public CPMBasicFile (String name, byte[] buffer)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
super (name, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public String getText ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
|
if (basicPreferences.showHeader)
|
||||||
|
text.append ("Name : " + name + "\n\n");
|
||||||
|
|
||||||
|
int ptr = 5;
|
||||||
|
while (buffer[ptr] != 0)
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if (showDebugText)
|
||||||
|
return debugText ();
|
||||||
|
|
||||||
|
ptr = 1;
|
||||||
|
while (ptr < buffer.length)
|
||||||
|
{
|
||||||
|
int nextAddress = getShort (buffer, ptr);
|
||||||
|
|
||||||
|
if (nextAddress == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int lineNumber = getShort (buffer, ptr + 2);
|
||||||
|
|
||||||
|
text.append (String.format (" %d ", lineNumber));
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int val = buffer[ptr++] & 0xFF;
|
||||||
|
|
||||||
|
if (val == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((val & 0x80) != 0)
|
||||||
|
{
|
||||||
|
if (val == 0xFF)
|
||||||
|
{
|
||||||
|
val = buffer[ptr++] & 0xFF;
|
||||||
|
String token = functions[val & 0x7F];
|
||||||
|
if (token.length () == 0)
|
||||||
|
token = String.format ("<FF %02X>", val);
|
||||||
|
text.append (token);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String token = tokens[val & 0x7F];
|
||||||
|
if (token.length () == 0)
|
||||||
|
token = String.format ("<%02X>", val);
|
||||||
|
text.append (token);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val >= 0x20 && val <= 0x7E) // printable
|
||||||
|
{
|
||||||
|
// check for stupid apostrophe comment
|
||||||
|
if (val == 0x3A && ptr + 1 < buffer.length && buffer[ptr] == (byte) 0x8F
|
||||||
|
&& buffer[ptr + 1] == (byte) 0xEA)
|
||||||
|
{
|
||||||
|
text.append ("'");
|
||||||
|
ptr += 2;
|
||||||
|
}
|
||||||
|
else if (val == 0x3A && ptr < buffer.length && buffer[ptr] == (byte) 0x9E)
|
||||||
|
{
|
||||||
|
// ignore colon before ELSE
|
||||||
|
}
|
||||||
|
else
|
||||||
|
text.append (String.format ("%s", (char) val));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val >= 0x11 && val <= 0x1A) // inline numbers
|
||||||
|
{
|
||||||
|
text.append (val - 0x11);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (val)
|
||||||
|
{
|
||||||
|
case 0x07:
|
||||||
|
text.append ("<BELL>");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x09:
|
||||||
|
text.append (" ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0A:
|
||||||
|
text.append ("\n ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0C:
|
||||||
|
text.append ("&H" + String.format ("%X", Utility.getShort (buffer, ptr)));
|
||||||
|
ptr += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0E: // same as 0x1C ??
|
||||||
|
text.append (Utility.getShort (buffer, ptr));
|
||||||
|
ptr += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0F:
|
||||||
|
text.append (buffer[ptr++] & 0xFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x1C: // same as 0x0E ??
|
||||||
|
text.append (Utility.getShort (buffer, ptr));
|
||||||
|
ptr += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x1D:
|
||||||
|
String d4 = Utility.floatValueMS4 (buffer, ptr) + "";
|
||||||
|
if (d4.endsWith (".0"))
|
||||||
|
d4 = d4.substring (0, d4.length () - 2);
|
||||||
|
text.append (d4 + "!");
|
||||||
|
ptr += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x1F:
|
||||||
|
String d8 = Utility.floatValueMS8 (buffer, ptr) + "";
|
||||||
|
if (d8.endsWith (".0"))
|
||||||
|
d8 = d8.substring (0, d8.length () - 2);
|
||||||
|
text.append (d8 + "#");
|
||||||
|
ptr += 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
text.append (String.format ("<%02X>", val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text.append ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utility.rtrim (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private String debugText ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
|
int ptr = 1;
|
||||||
|
int lastPtr;
|
||||||
|
|
||||||
|
while (ptr < buffer.length)
|
||||||
|
{
|
||||||
|
int nextAddress = getShort (buffer, ptr);
|
||||||
|
if (nextAddress == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int lineNumber = getShort (buffer, ptr + 2);
|
||||||
|
lastPtr = ptr;
|
||||||
|
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
int val;
|
||||||
|
while ((val = buffer[ptr++]) != 0)
|
||||||
|
{
|
||||||
|
ptr += switch (val)
|
||||||
|
{
|
||||||
|
case 0x0C, 0x0E, 0x1C -> 2; // 2 byte numeric
|
||||||
|
case 0x1D -> 4; // 4 byte single precision
|
||||||
|
case 0x1F -> 8; // 8 byte double precision
|
||||||
|
case 0x0F, 0xFF -> 1; // 1 byte numeric, function table entry
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
text.append (String.format (" %d %s%n", lineNumber,
|
||||||
|
HexFormatter.getHexString (buffer, lastPtr + 4, ptr - lastPtr - 4)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utility.rtrim (text);
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,10 @@ public class CPMTextFile extends TextFile
|
|||||||
{
|
{
|
||||||
String line = getLine (ptr);
|
String line = getLine (ptr);
|
||||||
text.append (line + "\n");
|
text.append (line + "\n");
|
||||||
ptr += line.length () + 2;
|
ptr += line.length () + 1;
|
||||||
|
if (ptr < buffer.length && buffer[ptr - 1] == 0x0D && buffer[ptr] == 0x0A)
|
||||||
|
++ptr;
|
||||||
|
|
||||||
while (ptr < buffer.length && buffer[ptr] == 0)
|
while (ptr < buffer.length && buffer[ptr] == 0)
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
@ -43,8 +46,8 @@ public class CPMTextFile extends TextFile
|
|||||||
{
|
{
|
||||||
StringBuilder line = new StringBuilder ();
|
StringBuilder line = new StringBuilder ();
|
||||||
|
|
||||||
int max = buffer.length - 1;
|
// int max = buffer.length - 1;
|
||||||
while (ptr < max && buffer[ptr] != 0x0D && buffer[ptr + 1] != 0x0A)
|
while (ptr < buffer.length && buffer[ptr] != 0x0D && buffer[ptr] != 0x0A)
|
||||||
line.append ((char) (buffer[ptr++] & 0x7F));
|
line.append ((char) (buffer[ptr++] & 0x7F));
|
||||||
|
|
||||||
return line.toString ();
|
return line.toString ();
|
||||||
|
@ -18,6 +18,7 @@ public class DefaultAppleFile extends AbstractFile
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super (name, buffer);
|
super (name, buffer);
|
||||||
|
|
||||||
this.text = "Name : " + name + "\n\n" + text;
|
this.text = "Name : " + name + "\n\n" + text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +36,10 @@ public class DefaultAppleFile extends AbstractFile
|
|||||||
{
|
{
|
||||||
if (text != null)
|
if (text != null)
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
return "Invalid file : " + name;
|
return "Invalid file : " + name;
|
||||||
|
|
||||||
return super.getText ();
|
return super.getText ();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,98 +18,101 @@ public abstract class HiResImage extends AbstractFile
|
|||||||
{
|
{
|
||||||
static final String[] auxTypes =
|
static final String[] auxTypes =
|
||||||
{ "Paintworks Packed SHR Image", "Packed Super Hi-Res Image",
|
{ "Paintworks Packed SHR Image", "Packed Super Hi-Res Image",
|
||||||
"Super Hi-Res Image (Apple Preferred Format)", "Packed QuickDraw II PICT File",
|
"Super Hi-Res Image (Apple Preferred Format)", "Packed QuickDraw II PICT File",
|
||||||
"Packed Super Hi-Res 3200 color image" };
|
"Packed Super Hi-Res 3200 color image", "DreamGraphix" };
|
||||||
|
|
||||||
static final int COLOR_TABLE_SIZE = 32;
|
static final int COLOR_TABLE_SIZE = 32;
|
||||||
static final int COLOR_TABLE_OFFSET_AUX_0 = 32_256;
|
static final int COLOR_TABLE_OFFSET_AUX_0 = 32_256;
|
||||||
static final int COLOR_TABLE_OFFSET_AUX_2 = 32_000;
|
static final int COLOR_TABLE_OFFSET_AUX_2 = 32_000;
|
||||||
public static final int FADDEN_AUX = 0x8066;
|
public static final int FADDEN_AUX = 0x8066;
|
||||||
|
|
||||||
private byte[] fourBuf = new byte[4];
|
private byte[] fourBuf = new byte[4];
|
||||||
private ColorTable defaultColorTable320 = new ColorTable (0, 0x00);
|
private ColorTable defaultColorTable320 = new ColorTable (0, 0x00);
|
||||||
private ColorTable defaultColorTable640 = new ColorTable (0, 0x80);
|
private ColorTable defaultColorTable640 = new ColorTable (0, 0x80);
|
||||||
|
|
||||||
// ---- ---- ------ -------------------------------------- ------------------------
|
// ---- ---- ------ -------------------------------------- ------------------------
|
||||||
// File Type Aux Name Description
|
// File Type Aux Name Description
|
||||||
// ---- ---- ------ -------------------------------------- ------------------------
|
// ---- ---- ------ -------------------------------------- ------------------------
|
||||||
// $06 BIN isGif() OriginalHiResImage
|
// $06 BIN isGif() OriginalHiResImage
|
||||||
// $06 BIN isPng() OriginalHiResImage
|
// $06 BIN isPng() OriginalHiResImage
|
||||||
// $06 BIN .BMP isBmp() OriginalHiResImage
|
// $06 BIN .BMP isBmp() OriginalHiResImage
|
||||||
// $06 BIN .AUX DoubleHiResImage
|
// $06 BIN .AUX DoubleHiResImage
|
||||||
// $06 BIN .PAC DoubleHiResImage
|
// $06 BIN .PAC DoubleHiResImage
|
||||||
// $06 BIN .A2FC DoubleHiResImage
|
// $06 BIN .A2FC DoubleHiResImage
|
||||||
// $06 BIN $2000 eof $4000 DoubleHiResImage
|
// $06 BIN $2000 eof $4000 DoubleHiResImage
|
||||||
// $06 BIN $1FFF eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
|
// $06 BIN $1FFF eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
|
||||||
// $06 BIN $2000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
|
// $06 BIN $2000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
|
||||||
// $06 BIN $4000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage (?)
|
// $06 BIN $4000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage (?)
|
||||||
// $06 BIN $4000 eof $4000 DoubleHiResImage (?)
|
// $06 BIN $4000 eof $4000 DoubleHiResImage (?)
|
||||||
// $06 BIN .3200 SHRPictureFile2
|
// $06 BIN .3200 SHRPictureFile2
|
||||||
// $06 BIN .3201 SHRPictureFile2 packed
|
// $06 BIN .3201 SHRPictureFile2 packed
|
||||||
// ---- ---- ------ -------------------------------------- ------------------------
|
// ---- ---- ------ -------------------------------------- ------------------------
|
||||||
// $08 FOT <$4000 Apple II Graphics File OriginalHiResImage
|
// $08 FOT <$4000 Apple II Graphics File OriginalHiResImage
|
||||||
// $08 FOT $4000 Packed Hi-Res file ???
|
// $08 FOT $4000 Packed Hi-Res file ???
|
||||||
// $08 FOT $4001 Packed Double Hi-Res file ???
|
// $08 FOT $4001 Packed Double Hi-Res file ???
|
||||||
// $08 FOT $8066 Fadden Hi-res FaddenHiResImage
|
// $08 FOT $8066 Fadden Hi-res FaddenHiResImage
|
||||||
// ---- ---- ------ -------------------------------------- ------------------------
|
// ---- ---- ------ -------------------------------------- ------------------------
|
||||||
// * $C0 PNT $0000 Paintworks Packed Super Hi-Res SHRPictureFile2
|
// * $C0 PNT $0000 Paintworks Packed Super Hi-Res SHRPictureFile2
|
||||||
// * $C0 PNT $0001 Packed IIGS Super Hi-Res Image SHRPictureFile2
|
// * $C0 PNT $0001 Packed IIGS Super Hi-Res Image SHRPictureFile2
|
||||||
// * $C0 PNT $0002 IIGS Super Hi-Res Picture File (APF) SHRPictureFile1
|
// * $C0 PNT $0002 IIGS Super Hi-Res Picture File (APF) SHRPictureFile1
|
||||||
// $C0 PNT $0003 Packed IIGS QuickDraw II PICT File SHRPictureFile2 *
|
// $C0 PNT $0003 Packed IIGS QuickDraw II PICT File SHRPictureFile2 *
|
||||||
// * $C0 PNT $0004 Packed Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3201
|
// * $C0 PNT $0004 Packed Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3201
|
||||||
// $C0 PNT $1000
|
// $C0 PNT $1000
|
||||||
// $C0 PNT $8000 Drawplus? Paintworks Gold?
|
// $C0 PNT $8000 Drawplus? Paintworks Gold?
|
||||||
// $C0 PNT $8001 GTv background picture
|
// $C0 PNT $8001 GTv background picture
|
||||||
// $C0 PNT $8005 DreamGraphix document
|
// $C0 PNT $8005 DreamGraphix document SHRPictureFile2
|
||||||
// $C0 PNT $8006 GIF
|
// $C0 PNT $8006 GIF
|
||||||
// ---- ---- ------ -------------------------------------- ------------------------
|
// ---- ---- ------ -------------------------------------- ------------------------
|
||||||
// * $C1 PIC $0000 IIGS Super Hi-Res Image SHRPictureFile2
|
// * $C1 PIC $0000 IIGS Super Hi-Res Image SHRPictureFile2
|
||||||
// $C1 PIC $0001 IIGS QuickDraw II PICT File SHRPictureFile2 *
|
// $C1 PIC $0001 IIGS QuickDraw II PICT File SHRPictureFile2 *
|
||||||
// * $C1 PIC $0002 Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3200
|
// * $C1 PIC $0002 Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3200
|
||||||
// $C1 PIC $2000 = $C1/0000
|
// $C1 PIC $2000 = $C1/0000
|
||||||
// $C1 PIC $4100 = $C1/0000
|
// $C1 PIC $4100 = $C1/0000
|
||||||
// $C1 PIC $4950 = $C1/0000
|
// $C1 PIC $4950 = $C1/0000
|
||||||
// $C1 PIC $8001 Allison raw image
|
// $C1 PIC $8001 Allison raw image
|
||||||
// $C1 PIC $8002 Thunderscan
|
// $C1 PIC $8002 Thunderscan
|
||||||
// $C1 PIC $8003 DreamGraphix
|
// $C1 PIC $8003 DreamGraphix
|
||||||
// ---- ---- ------ -------------------------------------- ------------------------
|
// ---- ---- ------ -------------------------------------- ------------------------
|
||||||
// $C2 ANI Paintworks animation
|
// $C2 ANI Paintworks animation
|
||||||
// $C3 PAL Paintworks palette
|
// $C3 PAL Paintworks palette
|
||||||
// ---- ---- ------ -------------------------------------- ------------------------
|
// ---- ---- ------ -------------------------------------- ------------------------
|
||||||
|
|
||||||
// packed unpacked
|
// packed unpacked
|
||||||
// $06.3200 1
|
// $06.3200 1
|
||||||
// $06.3201 .
|
// $06.3201 .
|
||||||
// $08 0000 .
|
// $08 0000 .
|
||||||
// $08 4000 .
|
// $08 4000 .
|
||||||
// $08 4001 .
|
// $08 4001 .
|
||||||
// $08 8066 3
|
// $08 8066 3
|
||||||
// $C0 0000 1
|
// $C0 0000 1
|
||||||
// $C0 0001 $C1 0000 2 1
|
// $C0 0001 $C1 0000 2 1
|
||||||
// $C0 0002 1,5
|
// $C0 0002 1,5
|
||||||
// $C0 0003 $C1 0001 . .
|
// $C0 0003 $C1 0001 . .
|
||||||
// $C0 0004 $C1 0002 . 1
|
// $C0 0004 $C1 0002 . 1
|
||||||
// $C0 1000 .
|
// $C0 1000 .
|
||||||
// $C0 8000 .
|
// $C0 8000 .
|
||||||
// $C0 8001 .
|
// $C0 8001 .
|
||||||
// $C0 8005 .
|
// $C0 8005 6
|
||||||
// $C0 8006 .
|
// $C0 8006 .
|
||||||
// $C1 0042 4
|
// $C1 0042 4
|
||||||
// $C1 0043 4
|
// $C1 0043 4
|
||||||
// $C1 2000 .
|
// $C1 2000 .
|
||||||
// $C1 4100 1
|
// $C1 4100 1
|
||||||
// $C1 4950 .
|
// $C1 4950 .
|
||||||
// $C1 8001 .
|
// $C1 8001 .
|
||||||
// $C1 8002 .
|
// $C1 8002 .
|
||||||
// $C1 8003 .
|
// $C1 8003 .
|
||||||
|
|
||||||
// 1 Graphics & Animation.2mg
|
// 1 Graphics & Animation.2mg
|
||||||
// 2 0603 Katie's Farm - Disk 2.po
|
// 2 0603 Katie's Farm - Disk 2.po
|
||||||
// 3 CompressedSlides.do
|
// 3 CompressedSlides.do
|
||||||
// 4 System Addons.hdv
|
// 4 System Addons.hdv
|
||||||
// 5 gfx.po
|
// 5 gfx.po
|
||||||
//
|
// 6 Dream Grafix v1.02.po
|
||||||
|
|
||||||
// see also - https://docs.google.com/spreadsheets/d
|
// see also - https://docs.google.com/spreadsheets/d
|
||||||
// /1rKR6A_bVniSCtIP_rrv8QLWJdj4h6jEU1jJj0AebWwg/edit#gid=0
|
// . /1rKR6A_bVniSCtIP_rrv8QLWJdj4h6jEU1jJj0AebWwg/edit#gid=0
|
||||||
|
// also - http://lukazi.blogspot.com/2017/03/double-high-resolution-graphics-dhgr.html
|
||||||
|
|
||||||
static PaletteFactory paletteFactory = new PaletteFactory ();
|
static PaletteFactory paletteFactory = new PaletteFactory ();
|
||||||
|
|
||||||
@ -297,7 +300,10 @@ public abstract class HiResImage extends AbstractFile
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ProdosConstants.FILE_TYPE_PNT: // 0xC0
|
case ProdosConstants.FILE_TYPE_PNT: // 0xC0
|
||||||
auxText = auxType > 4 ? "Unknown aux: " + auxType : auxTypes[auxType];
|
if (auxType == 0x8005)
|
||||||
|
auxText = auxTypes[5];
|
||||||
|
else
|
||||||
|
auxText = auxType > 4 ? "Unknown aux: " + auxType : auxTypes[auxType];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProdosConstants.FILE_TYPE_PIC: // 0xC1
|
case ProdosConstants.FILE_TYPE_PIC: // 0xC1
|
||||||
@ -495,7 +501,7 @@ public abstract class HiResImage extends AbstractFile
|
|||||||
int calculateBufferSize (byte[] buffer, int ptr)
|
int calculateBufferSize (byte[] buffer, int ptr)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
// int ptr = 0;
|
// int ptr = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
while (ptr < buffer.length)
|
while (ptr < buffer.length)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +70,8 @@ public class OriginalHiResImage extends HiResImage
|
|||||||
for (int ptr = base; ptr < max; ptr++)
|
for (int ptr = base; ptr < max; ptr++)
|
||||||
{
|
{
|
||||||
int value = buffer[ptr] & 0x7F;
|
int value = buffer[ptr] & 0x7F;
|
||||||
|
if ((buffer[ptr] & 0x80) != 0)
|
||||||
|
System.out.printf ("bit shift pixel found in %s%n", name);
|
||||||
for (int px = 0; px < 7; px++)
|
for (int px = 0; px < 7; px++)
|
||||||
{
|
{
|
||||||
int val = (value >> px) & 0x01;
|
int val = (value >> px) & 0x01;
|
||||||
|
@ -15,7 +15,7 @@ public class PascalProcedure
|
|||||||
byte[] buffer;
|
byte[] buffer;
|
||||||
int procOffset;
|
int procOffset;
|
||||||
int offset;
|
int offset;
|
||||||
int slot;
|
int procNo;
|
||||||
boolean valid;
|
boolean valid;
|
||||||
|
|
||||||
// only valid procedures have these fields
|
// only valid procedures have these fields
|
||||||
@ -25,17 +25,19 @@ public class PascalProcedure
|
|||||||
int codeEnd;
|
int codeEnd;
|
||||||
int parmSize;
|
int parmSize;
|
||||||
int dataSize;
|
int dataSize;
|
||||||
|
|
||||||
List<PascalCodeStatement> statements = new ArrayList<> ();
|
List<PascalCodeStatement> statements = new ArrayList<> ();
|
||||||
AssemblerProgram assembler;
|
AssemblerProgram assembler;
|
||||||
int jumpTable = -8;
|
int jumpTable = -8;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public PascalProcedure (byte[] buffer, int slot)
|
public PascalProcedure (byte[] buffer, int procNo)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.buffer = buffer;
|
this.buffer = buffer;
|
||||||
this.slot = slot;
|
this.procNo = procNo;
|
||||||
int p = buffer.length - 2 - slot * 2;
|
|
||||||
|
int p = buffer.length - 2 - procNo * 2;
|
||||||
offset = Utility.getShort (buffer, p);
|
offset = Utility.getShort (buffer, p);
|
||||||
procOffset = p - offset;
|
procOffset = p - offset;
|
||||||
valid = procOffset > 0;
|
valid = procOffset > 0;
|
||||||
@ -44,6 +46,7 @@ public class PascalProcedure
|
|||||||
{
|
{
|
||||||
procedureNo = buffer[procOffset] & 0xFF;
|
procedureNo = buffer[procOffset] & 0xFF;
|
||||||
procLevel = buffer[procOffset + 1] & 0xFF;
|
procLevel = buffer[procOffset + 1] & 0xFF;
|
||||||
|
|
||||||
codeStart = Utility.getShort (buffer, procOffset - 2);
|
codeStart = Utility.getShort (buffer, procOffset - 2);
|
||||||
codeEnd = Utility.getShort (buffer, procOffset - 4);
|
codeEnd = Utility.getShort (buffer, procOffset - 4);
|
||||||
parmSize = Utility.getShort (buffer, procOffset - 6);
|
parmSize = Utility.getShort (buffer, procOffset - 6);
|
||||||
@ -57,6 +60,7 @@ public class PascalProcedure
|
|||||||
{
|
{
|
||||||
if (statements.size () > 0 || assembler != null)
|
if (statements.size () > 0 || assembler != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int ptr = procOffset - codeStart - 2;
|
int ptr = procOffset - codeStart - 2;
|
||||||
int max = procOffset + jumpTable;
|
int max = procOffset + jumpTable;
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
final int segmentNoHeader;
|
final int segmentNoHeader;
|
||||||
private int segmentNoBody;
|
private int segmentNoBody;
|
||||||
// private final int blockOffset;
|
// private final int blockOffset;
|
||||||
// private final Relocator relocator;
|
|
||||||
boolean debug = false;
|
boolean debug = false;
|
||||||
|
|
||||||
public int blockNo;
|
public int blockNo;
|
||||||
@ -41,7 +40,6 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
|
|
||||||
this.slot = seq;
|
this.slot = seq;
|
||||||
// this.blockOffset = blockOffset;
|
// this.blockOffset = blockOffset;
|
||||||
// this.relocator = relocator;
|
|
||||||
|
|
||||||
this.blockNo = Utility.getShort (fullBuffer, seq * 4);
|
this.blockNo = Utility.getShort (fullBuffer, seq * 4);
|
||||||
this.size = Utility.getShort (fullBuffer, seq * 4 + 2);
|
this.size = Utility.getShort (fullBuffer, seq * 4 + 2);
|
||||||
@ -68,24 +66,6 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
|
|
||||||
int offset = blockNo * 512;
|
int offset = blockNo * 512;
|
||||||
|
|
||||||
// if (relocator != null)
|
|
||||||
// {
|
|
||||||
// // if (segmentNoHeader > 1)
|
|
||||||
// // {
|
|
||||||
// int sizeInBlocks = (size - 1) / BLOCK_SIZE + 1;
|
|
||||||
// int targetBlock = blockNo + blockOffset;
|
|
||||||
// addresses = relocator.getMultiDiskAddress (name, targetBlock, sizeInBlocks);
|
|
||||||
// if (addresses.size () > 0)
|
|
||||||
// {
|
|
||||||
// MultiDiskAddress multiDiskAddress = addresses.get (0);
|
|
||||||
// if (multiDiskAddress.diskNumber == 1)
|
|
||||||
// offset = (multiDiskAddress.physicalBlockNumber - blockOffset) * BLOCK_SIZE;
|
|
||||||
// else
|
|
||||||
// offset = -1;
|
|
||||||
// }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
{
|
{
|
||||||
buffer = new byte[0];
|
buffer = new byte[0];
|
||||||
@ -110,11 +90,6 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void setMultiDiskAddresses (List<MultiDiskAddress> addresses)
|
|
||||||
// {
|
|
||||||
// this.addresses = addresses;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private void buildProcedureList ()
|
private void buildProcedureList ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -132,10 +107,9 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
int sizeInBlocks = (size - 1) / BLOCK_SIZE + 1;
|
int sizeInBlocks = (size - 1) / BLOCK_SIZE + 1;
|
||||||
|
|
||||||
return String.format (
|
return String.format (
|
||||||
" %2d %02X %02X %04X %-8s %-15s%3d " + "%02X %d %d %d %d %s",
|
" %2d %02X %02X %04X %-8s %-15s%3d " + "%02X %d %d %d %d", slot,
|
||||||
slot, blockNo, sizeInBlocks, size, name, SegmentKind[segKind], textAddress,
|
blockNo, sizeInBlocks, size, name, SegmentKind[segKind], textAddress,
|
||||||
segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2,
|
segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2);
|
||||||
getMultiDiskAddresses ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -152,14 +126,13 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
+ "===============================".substring (0, title.length ()) + "\n\n");
|
+ "===============================".substring (0, title.length ()) + "\n\n");
|
||||||
String warning = segmentNoBody == segmentNoHeader ? ""
|
String warning = segmentNoBody == segmentNoHeader ? ""
|
||||||
: String.format (" (%02X in routine)", segmentNoBody);
|
: String.format (" (%02X in routine)", segmentNoBody);
|
||||||
text.append (String.format ("Address........ %02X%n", blockNo));
|
text.append (
|
||||||
// if (addresses != null)
|
String.format ("Segment........ %02X%s%n", segmentNoHeader, warning));
|
||||||
text.append (String.format ("Multi disk .... %s%n", getMultiDiskAddresses ()));
|
text.append (String.format ("Address........ %02X%n", blockNo));
|
||||||
text.append (String.format ("Length......... %04X%n", buffer.length));
|
text.append (String.format ("Length......... %04X%n", buffer.length));
|
||||||
text.append (String.format ("Machine type... %d%n", machineType));
|
text.append (String.format ("Machine type... %d%n", machineType));
|
||||||
text.append (String.format ("Version........ %d%n", version));
|
text.append (String.format ("Version........ %d%n", version));
|
||||||
text.append (String.format ("Segment........ %02X%s%n", segmentNoHeader, warning));
|
text.append (String.format ("Total procs.... %2d%n", procedures.size ()));
|
||||||
text.append (String.format ("Total procs.... %d%n", procedures.size ()));
|
|
||||||
|
|
||||||
text.append ("\nProcedure Dictionary\n====================\n\n");
|
text.append ("\nProcedure Dictionary\n====================\n\n");
|
||||||
|
|
||||||
@ -174,7 +147,7 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
{
|
{
|
||||||
if (procedure.valid)
|
if (procedure.valid)
|
||||||
{
|
{
|
||||||
int address = size - procedure.slot * 2 - 2;
|
int address = size - procedure.procNo * 2 - 2;
|
||||||
text.append (String.format (
|
text.append (String.format (
|
||||||
" %3d %04X %3d %04X %04X %04X %04X (%04X - %04X = %04X)%n",
|
" %3d %04X %3d %04X %04X %04X %04X (%04X - %04X = %04X)%n",
|
||||||
procedure.procedureNo, procedure.offset, procedure.procLevel,
|
procedure.procedureNo, procedure.offset, procedure.procLevel,
|
||||||
@ -182,7 +155,7 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
procedure.dataSize, address, procedure.offset, procedure.procOffset));
|
procedure.dataSize, address, procedure.offset, procedure.procOffset));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
text.append (String.format (" %3d %04X%n", procedure.slot, procedure.offset));
|
text.append (String.format (" %3d %04X%n", procedure.procNo, procedure.offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
text.append ("\nStrings\n=======\n");
|
text.append ("\nStrings\n=======\n");
|
||||||
@ -200,39 +173,4 @@ public class PascalSegment extends AbstractFile implements PascalConstants
|
|||||||
|
|
||||||
return text.toString ();
|
return text.toString ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
private String getMultiDiskAddresses ()
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
String multiDiskAddressText = "";
|
|
||||||
// int sizeInBlocks = (size - 1) / BLOCK_SIZE + 1;
|
|
||||||
|
|
||||||
// if (segmentNoHeader == 1) // main segment
|
|
||||||
// {
|
|
||||||
// multiDiskAddressText = String.format ("1:%03X", (blockNo + blockOffset));
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// if (relocator != null)
|
|
||||||
// {
|
|
||||||
// int targetBlock = blockNo + blockOffset;
|
|
||||||
// List<MultiDiskAddress> addresses =
|
|
||||||
// relocator.getMultiDiskAddress (name, targetBlock, sizeInBlocks);
|
|
||||||
// if (addresses.isEmpty ())
|
|
||||||
// multiDiskAddressText = ".";
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// StringBuilder locations = new StringBuilder ();
|
|
||||||
// for (MultiDiskAddress multiDiskAddress : addresses)
|
|
||||||
// locations.append (multiDiskAddress.toString () + ", ");
|
|
||||||
// if (locations.length () > 2)
|
|
||||||
// {
|
|
||||||
// locations.deleteCharAt (locations.length () - 1);
|
|
||||||
// locations.deleteCharAt (locations.length () - 1);
|
|
||||||
// }
|
|
||||||
// multiDiskAddressText = locations.toString ();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return multiDiskAddressText;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -4,6 +4,8 @@ package com.bytezone.diskbrowser.applefile;
|
|||||||
public class PascalText extends TextFile
|
public class PascalText extends TextFile
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
private final static int PAGE_SIZE = 1024;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public PascalText (String name, byte[] buffer)
|
public PascalText (String name, byte[] buffer)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -16,26 +18,34 @@ public class PascalText extends TextFile
|
|||||||
public String getText ()
|
public String getText ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
// Text files are broken up into 1024-byte pages.
|
||||||
|
// [DLE] [indent] [text] [CR] ... [nulls]
|
||||||
|
|
||||||
StringBuilder text = new StringBuilder (getHeader ());
|
StringBuilder text = new StringBuilder (getHeader ());
|
||||||
|
|
||||||
int ptr = 0x400;
|
int ptr = PAGE_SIZE; // skip text editor header
|
||||||
|
|
||||||
while (ptr < buffer.length)
|
while (ptr < buffer.length)
|
||||||
{
|
{
|
||||||
if (buffer[ptr] == 0x00)
|
if (buffer[ptr] == 0x00) // padding to page boundary
|
||||||
{
|
{
|
||||||
++ptr;
|
ptr = (ptr / PAGE_SIZE + 1) * PAGE_SIZE; // skip to next page
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (buffer[ptr] == 0x10)
|
|
||||||
|
if (buffer[ptr] == 0x10) // Data Link Escape code
|
||||||
{
|
{
|
||||||
int tab = buffer[ptr + 1] - 0x20;
|
int tab = (buffer[ptr + 1] & 0xFF) - 32; // indent amaount
|
||||||
while (tab-- > 0)
|
while (tab-- > 0)
|
||||||
text.append (" ");
|
text.append (" ");
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
String line = getLine (ptr);
|
|
||||||
text.append (line + "\n");
|
while (buffer[ptr] != 0x0D)
|
||||||
ptr += line.length () + 1;
|
text.append ((char) buffer[ptr++]);
|
||||||
|
|
||||||
|
text.append ("\n");
|
||||||
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text.length () > 0)
|
if (text.length () > 0)
|
||||||
@ -43,14 +53,4 @@ public class PascalText extends TextFile
|
|||||||
|
|
||||||
return text.toString ();
|
return text.toString ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
private String getLine (int ptr)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
StringBuilder line = new StringBuilder ();
|
|
||||||
while (buffer[ptr] != 0x0D)
|
|
||||||
line.append ((char) buffer[ptr++]);
|
|
||||||
return line.toString ();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ package com.bytezone.diskbrowser.applefile;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
||||||
import com.bytezone.diskbrowser.prodos.DirectoryHeader;
|
import com.bytezone.diskbrowser.prodos.DirectoryHeader;
|
||||||
@ -15,7 +16,8 @@ import com.bytezone.diskbrowser.utilities.Utility;
|
|||||||
public class ProdosDirectory extends AbstractFile implements ProdosConstants
|
public class ProdosDirectory extends AbstractFile implements ProdosConstants
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
static final DateTimeFormatter df = DateTimeFormatter.ofPattern ("d-LLL-yy");
|
private static Locale US = Locale.US; // to force 3 character months
|
||||||
|
static final DateTimeFormatter df = DateTimeFormatter.ofPattern ("d-LLL-yy", US);
|
||||||
static final DateTimeFormatter tf = DateTimeFormatter.ofPattern ("H:mm");
|
static final DateTimeFormatter tf = DateTimeFormatter.ofPattern ("H:mm");
|
||||||
static final String UNDERLINE =
|
static final String UNDERLINE =
|
||||||
"----------------------------------------------------\n";
|
"----------------------------------------------------\n";
|
||||||
@ -86,7 +88,6 @@ public class ProdosDirectory extends AbstractFile implements ProdosConstants
|
|||||||
int nameLength = buffer[i] & 0x0F;
|
int nameLength = buffer[i] & 0x0F;
|
||||||
String filename = HexFormatter.getString (buffer, i + 1, nameLength);
|
String filename = HexFormatter.getString (buffer, i + 1, nameLength);
|
||||||
String subType = "";
|
String subType = "";
|
||||||
String locked;
|
|
||||||
|
|
||||||
switch (storageType)
|
switch (storageType)
|
||||||
{
|
{
|
||||||
@ -121,12 +122,12 @@ public class ProdosDirectory extends AbstractFile implements ProdosConstants
|
|||||||
|
|
||||||
int eof = Utility.intValue (buffer[i + 21], buffer[i + 22], buffer[i + 23]);
|
int eof = Utility.intValue (buffer[i + 21], buffer[i + 22], buffer[i + 23]);
|
||||||
int fileType = buffer[i + 16] & 0xFF;
|
int fileType = buffer[i + 16] & 0xFF;
|
||||||
locked = (buffer[i + 30] & 0xE0) == 0xE0 ? " " : "*";
|
String locked = (buffer[i + 30] & 0xE0) == 0xE0 ? " " : "*";
|
||||||
|
int aux = Utility.getShort (buffer, i + 31);
|
||||||
|
|
||||||
switch (fileType)
|
switch (fileType)
|
||||||
{
|
{
|
||||||
case FILE_TYPE_TEXT:
|
case FILE_TYPE_TEXT:
|
||||||
int aux = Utility.getShort (buffer, i + 31);
|
|
||||||
subType = String.format ("R=%5d", aux);
|
subType = String.format ("R=%5d", aux);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -134,14 +135,13 @@ public class ProdosDirectory extends AbstractFile implements ProdosConstants
|
|||||||
case FILE_TYPE_PNT:
|
case FILE_TYPE_PNT:
|
||||||
case FILE_TYPE_PIC:
|
case FILE_TYPE_PIC:
|
||||||
case FILE_TYPE_FOT:
|
case FILE_TYPE_FOT:
|
||||||
aux = Utility.getShort (buffer, i + 31);
|
|
||||||
subType = String.format ("A=$%4X", aux);
|
subType = String.format ("A=$%4X", aux);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_TYPE_AWP:
|
case FILE_TYPE_AWP:
|
||||||
aux = Utility.intValue (buffer[i + 32], buffer[i + 31]); // backwards!
|
int flags = Utility.intValue (buffer[i + 32], buffer[i + 31]); // aux backwards!
|
||||||
if (aux != 0)
|
if (flags != 0)
|
||||||
filename = convert (filename, aux);
|
filename = convert (filename, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -149,9 +149,10 @@ public class ProdosDirectory extends AbstractFile implements ProdosConstants
|
|||||||
}
|
}
|
||||||
|
|
||||||
String forkFlag = storageType == 5 ? "+" : " ";
|
String forkFlag = storageType == 5 ? "+" : " ";
|
||||||
text.append (String.format ("%s%-15s %3s%s %5d %9s %5s %9s %5s %8d %7s%n",
|
text.append (
|
||||||
locked, filename, ProdosConstants.fileTypes[type], forkFlag, blocks, dateM,
|
String.format ("%s%-15s %3s%s %5d %9s %5s %9s %5s %8d %7s %04X%n",
|
||||||
timeM, dateC, timeC, eof, subType));
|
locked, filename, ProdosConstants.fileTypes[type], forkFlag, blocks,
|
||||||
|
dateM, timeM, dateC, timeC, eof, subType, aux));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -88,8 +88,8 @@ public class QuickDrawFont extends CharacterList
|
|||||||
firstChar = Utility.getShort (buffer, ptr + 2);
|
firstChar = Utility.getShort (buffer, ptr + 2);
|
||||||
lastChar = Utility.getShort (buffer, ptr + 4);
|
lastChar = Utility.getShort (buffer, ptr + 4);
|
||||||
widMax = Utility.getShort (buffer, ptr + 6);
|
widMax = Utility.getShort (buffer, ptr + 6);
|
||||||
kernMax = Utility.signedShort (buffer, ptr + 8);
|
kernMax = Utility.getSignedShort (buffer, ptr + 8);
|
||||||
nDescent = Utility.signedShort (buffer, ptr + 10);
|
nDescent = Utility.getSignedShort (buffer, ptr + 10);
|
||||||
fRectWidth = Utility.getShort (buffer, ptr + 12);
|
fRectWidth = Utility.getShort (buffer, ptr + 12);
|
||||||
fRectHeight = Utility.getShort (buffer, ptr + 14);
|
fRectHeight = Utility.getShort (buffer, ptr + 14);
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ public class SHRPictureFile1 extends HiResImage
|
|||||||
int lo = dirEntry.mode & 0x00FF; // mode bit if hi == 0
|
int lo = dirEntry.mode & 0x00FF; // mode bit if hi == 0
|
||||||
|
|
||||||
boolean fillMode = (dirEntry.mode & 0x20) != 0;
|
boolean fillMode = (dirEntry.mode & 0x20) != 0;
|
||||||
// assert fillMode == false;
|
// assert fillMode == false;
|
||||||
|
|
||||||
if (hi != 0)
|
if (hi != 0)
|
||||||
System.out.println ("hi not zero");
|
System.out.println ("hi not zero");
|
||||||
@ -242,7 +242,8 @@ public class SHRPictureFile1 extends HiResImage
|
|||||||
if (ptr < data.length - 32)
|
if (ptr < data.length - 32)
|
||||||
colorTables[i] = new ColorTable (i, data, ptr);
|
colorTables[i] = new ColorTable (i, data, ptr);
|
||||||
else
|
else
|
||||||
colorTables[i] = new ColorTable (i, 0x00); // default empty table !! not finished
|
colorTables[i] = new ColorTable (i, 0x00); // default empty table !! not
|
||||||
|
// finished
|
||||||
ptr += 32;
|
ptr += 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,11 +333,11 @@ public class SHRPictureFile1 extends HiResImage
|
|||||||
ptr = 0;
|
ptr = 0;
|
||||||
for (int line = 0; line < numScanLines; line++)
|
for (int line = 0; line < numScanLines; line++)
|
||||||
{
|
{
|
||||||
// if (isOddAndEmpty (packedScanLines[line]))
|
// if (isOddAndEmpty (packedScanLines[line]))
|
||||||
// {
|
// {
|
||||||
// System.out.println ("Odd number of bytes in empty buffer in " + name);
|
// System.out.println ("Odd number of bytes in empty buffer in " + name);
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
int bytesUnpacked = unpack (packedScanLines[line], 0,
|
int bytesUnpacked = unpack (packedScanLines[line], 0,
|
||||||
packedScanLines[line].length, unpackedBuffer, ptr);
|
packedScanLines[line].length, unpackedBuffer, ptr);
|
||||||
@ -352,16 +353,17 @@ public class SHRPictureFile1 extends HiResImage
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------//
|
// -------------------------------------------------------------------------------//
|
||||||
// private boolean isOddAndEmpty (byte[] buffer)
|
// private boolean isOddAndEmpty (byte[] buffer)
|
||||||
// // -------------------------------------------------------------------------------//
|
// //
|
||||||
// {
|
// -------------------------------------------------------------------------------//
|
||||||
// if (buffer.length % 2 == 0)
|
// {
|
||||||
// return false;
|
// if (buffer.length % 2 == 0)
|
||||||
// for (byte b : buffer)
|
// return false;
|
||||||
// if (b != 0)
|
// for (byte b : buffer)
|
||||||
// return false;
|
// if (b != 0)
|
||||||
// return true;
|
// return false;
|
||||||
// }
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------//
|
// -------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,6 +5,7 @@ import java.awt.image.DataBuffer;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.nufx.LZW3;
|
||||||
import com.bytezone.diskbrowser.prodos.ProdosConstants;
|
import com.bytezone.diskbrowser.prodos.ProdosConstants;
|
||||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
import com.bytezone.diskbrowser.utilities.Utility;
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
@ -144,6 +145,36 @@ public class SHRPictureFile2 extends HiResImage
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x8005:
|
||||||
|
int ptr = buffer.length - 17;
|
||||||
|
|
||||||
|
int imageType = Utility.getShort (buffer, ptr);
|
||||||
|
int imageHeight = Utility.getShort (buffer, ptr + 2);
|
||||||
|
int imageWidth = Utility.getShort (buffer, ptr + 4);
|
||||||
|
|
||||||
|
String id = HexFormatter.getPascalString (buffer, ptr + 6);
|
||||||
|
assert "DreamWorld".equals (id);
|
||||||
|
|
||||||
|
int expectedLen = 32000 + 512;
|
||||||
|
if (imageType == 0) // 256 colours
|
||||||
|
expectedLen += (256 + 512);
|
||||||
|
else // 3200 colours
|
||||||
|
expectedLen += 6400;
|
||||||
|
|
||||||
|
byte[] dstBuffer = new byte[expectedLen + 1024];
|
||||||
|
LZW3 lzw3 = new LZW3 ();
|
||||||
|
int bytes = lzw3.unpack (buffer, dstBuffer, expectedLen);
|
||||||
|
buffer = dstBuffer;
|
||||||
|
|
||||||
|
colorTables = new ColorTable[imageHeight];
|
||||||
|
for (int i = 0; i < colorTables.length; i++)
|
||||||
|
{
|
||||||
|
colorTables[i] = new ColorTable (i, this.buffer, 32000 + i * COLOR_TABLE_SIZE);
|
||||||
|
colorTables[i].reverse ();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.printf ("%s: PNT unknown aux: %04X%n", name, auxType);
|
System.out.printf ("%s: PNT unknown aux: %04X%n", name, auxType);
|
||||||
failureReason = "unknown PNT aux";
|
failureReason = "unknown PNT aux";
|
||||||
|
@ -1,16 +1,40 @@
|
|||||||
package com.bytezone.diskbrowser.applefile;
|
package com.bytezone.diskbrowser.applefile;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class SegmentDictionary
|
public class SegmentDictionary
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final boolean isValid;
|
private final boolean isValid;
|
||||||
|
private int[] codeAddress = new int[16];
|
||||||
|
private int[] codeLength = new int[16];
|
||||||
|
private String[] segName = new String[16];
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public SegmentDictionary (String name, byte[] buffer)
|
public SegmentDictionary (String name, byte[] buffer)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
isValid = !name.equals ("SYSTEM.INTERP"); // temporary
|
isValid = !name.equals ("SYSTEM.INTERP"); // temporary
|
||||||
|
|
||||||
|
int ptr = 0;
|
||||||
|
for (int seg = 0; seg < 16; seg++)
|
||||||
|
{
|
||||||
|
codeAddress[seg] = Utility.getShort (buffer, ptr);
|
||||||
|
ptr += 2;
|
||||||
|
codeLength[seg] = Utility.getShort (buffer, ptr);
|
||||||
|
ptr += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = 64;
|
||||||
|
for (int seg = 0; seg < 16; seg++)
|
||||||
|
{
|
||||||
|
segName[seg] = new String (buffer, ptr, 8);
|
||||||
|
ptr += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (int seg = 0; seg < 16; seg++)
|
||||||
|
// System.out.printf ("%04X %04X %s%n", codeAddress[seg], codeLength[seg], segName[seg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -52,7 +52,7 @@ public class StoredVariables extends AbstractFile
|
|||||||
else if (suffix == '%')
|
else if (suffix == '%')
|
||||||
{
|
{
|
||||||
intValue = Utility.intValue (buffer[ptr + 3], buffer[ptr + 2]); // backwards!
|
intValue = Utility.intValue (buffer[ptr + 3], buffer[ptr + 2]); // backwards!
|
||||||
if ((buffer[ptr + 2] & 0x80) > 0)
|
if ((buffer[ptr + 2] & 0x80) != 0)
|
||||||
intValue -= 65536;
|
intValue -= 65536;
|
||||||
text.append (" = " + intValue);
|
text.append (" = " + intValue);
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ public class StoredVariables extends AbstractFile
|
|||||||
{
|
{
|
||||||
if (hasValue (ptr + 2))
|
if (hasValue (ptr + 2))
|
||||||
{
|
{
|
||||||
String value = HexFormatter.floatValue (buffer, ptr + 2) + "";
|
String value = Utility.floatValue (buffer, ptr + 2) + "";
|
||||||
if (value.endsWith (".0"))
|
if (value.endsWith (".0"))
|
||||||
text.append (" = " + value.substring (0, value.length () - 2));
|
text.append (" = " + value.substring (0, value.length () - 2));
|
||||||
else
|
else
|
||||||
@ -101,7 +101,7 @@ public class StoredVariables extends AbstractFile
|
|||||||
suffix = ' ';
|
suffix = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer variableName = new StringBuffer ();
|
StringBuilder variableName = new StringBuilder ();
|
||||||
variableName.append (c1);
|
variableName.append (c1);
|
||||||
if (c2 > 32)
|
if (c2 > 32)
|
||||||
variableName.append (c2);
|
variableName.append (c2);
|
||||||
@ -116,12 +116,14 @@ public class StoredVariables extends AbstractFile
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder ("(");
|
StringBuilder text = new StringBuilder ("(");
|
||||||
|
|
||||||
for (int i = 0; i < values.length; i++)
|
for (int i = 0; i < values.length; i++)
|
||||||
{
|
{
|
||||||
text.append (values[i]);
|
text.append (values[i]);
|
||||||
if (i < values.length - 1)
|
if (i < values.length - 1)
|
||||||
text.append (',');
|
text.append (',');
|
||||||
}
|
}
|
||||||
|
|
||||||
return text.append (')').toString ();
|
return text.append (')').toString ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +180,7 @@ public class StoredVariables extends AbstractFile
|
|||||||
else if (elementSize == 5)
|
else if (elementSize == 5)
|
||||||
{
|
{
|
||||||
if (hasValue (p))
|
if (hasValue (p))
|
||||||
text.append (HexFormatter.floatValue (buffer, p));
|
text.append (Utility.floatValue (buffer, p));
|
||||||
text.append ("\n");
|
text.append ("\n");
|
||||||
}
|
}
|
||||||
p += elementSize;
|
p += elementSize;
|
||||||
@ -201,6 +203,7 @@ public class StoredVariables extends AbstractFile
|
|||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
if (buffer[p + i] != 0)
|
if (buffer[p + i] != 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ public class SubLine implements ApplesoftConstants
|
|||||||
private void checkFunction (String var, byte terminator)
|
private void checkFunction (String var, byte terminator)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
assert terminator == ASCII_LEFT_BRACKET;
|
// assert terminator == ASCII_LEFT_BRACKET;
|
||||||
|
|
||||||
if (!functions.contains (var))
|
if (!functions.contains (var))
|
||||||
functions.add (var);
|
functions.add (var);
|
||||||
|
@ -47,8 +47,8 @@ public class UserBasicFormatter extends BasicFormatter
|
|||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder (String.format ("%5d", (line.lineNumber)));
|
StringBuilder text = new StringBuilder (String.format ("%5d", (line.lineNumber)));
|
||||||
|
|
||||||
int indentLevel = loopVariables.size (); // each full line starts at the loop indent
|
int indentLevel = loopVariables.size (); // each full line starts at the loop indent
|
||||||
int ifIndent = 0; // IF statement(s) limit back indentation by NEXT
|
int ifIndent = 0; // IF statement(s) limit back indentation by NEXT
|
||||||
|
|
||||||
for (SubLine subline : line.sublines)
|
for (SubLine subline : line.sublines)
|
||||||
{
|
{
|
||||||
@ -107,7 +107,7 @@ public class UserBasicFormatter extends BasicFormatter
|
|||||||
String lineText = alignment.getAlignedText (subline);
|
String lineText = alignment.getAlignedText (subline);
|
||||||
|
|
||||||
if (subline.is (TOKEN_DATA) && basicPreferences.deleteExtraDataSpace)
|
if (subline.is (TOKEN_DATA) && basicPreferences.deleteExtraDataSpace)
|
||||||
lineText = lineText.replaceFirst ("DATA ", "DATA ");
|
lineText = lineText.replaceFirst ("DATA +", "DATA "); // regex
|
||||||
|
|
||||||
// Check for a wrappable REM/DATA/DIM statement
|
// Check for a wrappable REM/DATA/DIM statement
|
||||||
// (see SEA BATTLE on DISK283.DSK)
|
// (see SEA BATTLE on DISK283.DSK)
|
||||||
|
@ -22,10 +22,19 @@
|
|||||||
0035 YSAV1
|
0035 YSAV1
|
||||||
0036 CSWL
|
0036 CSWL
|
||||||
0037 CSHW
|
0037 CSHW
|
||||||
0044 A5L - volume number?
|
003D A1H
|
||||||
|
003C A1L
|
||||||
|
003F A2H
|
||||||
|
003E A2L
|
||||||
|
0041 A3H
|
||||||
|
0040 A3L
|
||||||
|
0043 A4H
|
||||||
|
0042 A4L
|
||||||
|
0045 A5H
|
||||||
|
0044 A5L
|
||||||
004E RND-LO
|
004E RND-LO
|
||||||
004F RND-HI
|
004F RND-HI
|
||||||
0050 LINNUM
|
0050 LINNUM line number, unsigned word
|
||||||
0067 Basic program address LO
|
0067 Basic program address LO
|
||||||
0068 Basic program address HI
|
0068 Basic program address HI
|
||||||
0069 Basic variables address LO
|
0069 Basic variables address LO
|
||||||
@ -52,8 +61,48 @@
|
|||||||
0200 Input buffer
|
0200 Input buffer
|
||||||
|
|
||||||
03D0 Applesoft warm start
|
03D0 Applesoft warm start
|
||||||
03EA VECT
|
|
||||||
A56E catalog routine
|
03F2 RST: Control-reset vector
|
||||||
|
03F3 RST: Control-reset vector
|
||||||
|
03F4 RST: Control-reset checksum (EOR #$A5)
|
||||||
|
03FB NMI: Non-Maskable Interrupt vector
|
||||||
|
03FC NMI: Non-Maskable Interrupt vector
|
||||||
|
03F8 USR: user vector (Control-Y)
|
||||||
|
03F9 USR: user vector (Control-Y)
|
||||||
|
03FE IRQ: Interrupt Request/BRK vector
|
||||||
|
03FF IRQ: Interrupt Request/BRK vector
|
||||||
|
|
||||||
|
A54F DOS 3.3 INIT
|
||||||
|
A413 DOS 3.3 LOAD
|
||||||
|
A397 DOS 3.3 SAVE
|
||||||
|
A4D1 DOS 3.3 RUN
|
||||||
|
A4F0 DOS 3.3 CHAIN
|
||||||
|
A263 DOS 3.3 DELETE
|
||||||
|
A271 DOS 3.3 LOCK
|
||||||
|
A275 DOS 3.3 UNLOCK
|
||||||
|
A2EA DOS 3.3 CLOSE
|
||||||
|
A51B DOS 3.3 READ
|
||||||
|
A5C6 DOS 3.3 EXEC
|
||||||
|
A510 DOS 3.3 WRITE
|
||||||
|
A5DD DOS 3.3 POSITION
|
||||||
|
A2A3 DOS 3.3 OPEN
|
||||||
|
A298 DOS 3.3 APPEND
|
||||||
|
A281 DOS 3.3 RENAME
|
||||||
|
A56E DOS 3.3 CATALOG
|
||||||
|
A233 DOS 3.3 MON
|
||||||
|
A23D DOS 3.3 NOMON
|
||||||
|
A229 DOS 3.3 PR#
|
||||||
|
A22E DOS 3.3 IN#
|
||||||
|
A251 DOS 3.3 MAXFILES
|
||||||
|
A57A DOS 3.3 FP
|
||||||
|
A59E DOS 3.3 INT
|
||||||
|
A331 DOS 3.3 BSAVE
|
||||||
|
A35D DOS 3.3 BLOAD
|
||||||
|
A38E DOS 3.3 BRUN
|
||||||
|
A27D DOS 3.3 VERIFY
|
||||||
|
|
||||||
|
BF00 ProDOS MLI entry point
|
||||||
|
BF98 ProDOS Machine ID Byte
|
||||||
|
|
||||||
* C000 80STOREOFF Allow page2 to switch video page1 page2
|
* C000 80STOREOFF Allow page2 to switch video page1 page2
|
||||||
C001 80STOREON Allow page2 to switch main & aux video memory
|
C001 80STOREON Allow page2 to switch main & aux video memory
|
||||||
@ -68,8 +117,12 @@ C009 ALTZPON Enable aux memory from $0000-$01FF & avl BSR
|
|||||||
C00A SLOTC3ROMOFF Enable main ROM from $C300-$C3FF
|
C00A SLOTC3ROMOFF Enable main ROM from $C300-$C3FF
|
||||||
C00B SLOTC3ROMON Enable slot ROM from $C300-$C3FF
|
C00B SLOTC3ROMON Enable slot ROM from $C300-$C3FF
|
||||||
|
|
||||||
C000 KYBD - last key pressed
|
C000 KBD - Last key pressed
|
||||||
C010 STROBE - Clear KYBD
|
C010 KBDSTRB - Clear KYBD
|
||||||
|
C019 VBL - Vertical Blank
|
||||||
|
C020 TAPEOUT - Toggle cassette output
|
||||||
|
C030 SPKR - Toggle speaker
|
||||||
|
C040 STROBE - Output strobe pulse to game I/O connector
|
||||||
C050 TXTCLR - Display Graphics
|
C050 TXTCLR - Display Graphics
|
||||||
C051 TXTSET - Display Text
|
C051 TXTSET - Display Text
|
||||||
C052 MIXCLR - Display Full Screen
|
C052 MIXCLR - Display Full Screen
|
||||||
@ -78,6 +131,15 @@ C054 TXTPAGE1 - Display Page 1
|
|||||||
C055 TXTPAGE2 - If 80STORE Off: Display Page 2, If 80STORE On: Read/Write Aux Display Mem
|
C055 TXTPAGE2 - If 80STORE Off: Display Page 2, If 80STORE On: Read/Write Aux Display Mem
|
||||||
C056 LORES - Display LoRes Graphics
|
C056 LORES - Display LoRes Graphics
|
||||||
C057 HIRES - Display HiRes Graphics
|
C057 HIRES - Display HiRes Graphics
|
||||||
|
C060 TAPEIN - Read audio from cassette input
|
||||||
|
C061 PB0 - Read joystick button 0/Open-Apple key
|
||||||
|
C062 PB1 - Read joystick button 1/Closed-Apple key
|
||||||
|
C063 PB2 - Read joystick button 2
|
||||||
|
C064 PADDL0 - Read paddle/joystick 0
|
||||||
|
C065 PADDL1 - Read paddle/joystick 1
|
||||||
|
C066 PADDL2 - Read paddle/joystick 2
|
||||||
|
C067 PADDL3 - Read paddle/joystick 3
|
||||||
|
C070 PTRIG - Clear paddle/joystick timer
|
||||||
|
|
||||||
C080 Read RAM bank 2; no write
|
C080 Read RAM bank 2; no write
|
||||||
C081 ROMIN - Read ROM; write RAM bank 2
|
C081 ROMIN - Read ROM; write RAM bank 2
|
||||||
@ -96,6 +158,9 @@ C08D Read ROM; write RAM bank 1
|
|||||||
C08E Read ROM; no write
|
C08E Read ROM; no write
|
||||||
C08F Read/write RAM bank 1
|
C08F Read/write RAM bank 1
|
||||||
|
|
||||||
|
C600 BOOT0 - Disk II controller ROM
|
||||||
|
0801 BOOT1 - Disk II bootstrap RAM
|
||||||
|
|
||||||
D52C INLIN numeric input
|
D52C INLIN numeric input
|
||||||
DB3A STROUT - output a string
|
DB3A STROUT - output a string
|
||||||
DB5C output a character
|
DB5C output a character
|
||||||
@ -106,6 +171,7 @@ DEC0 SYNCHR
|
|||||||
DEC9 syntax error
|
DEC9 syntax error
|
||||||
DFE3 PTRGET
|
DFE3 PTRGET
|
||||||
|
|
||||||
|
E000 Applesoft BASIC entry
|
||||||
E053 find a variable
|
E053 find a variable
|
||||||
E10C convert FP to INT
|
E10C convert FP to INT
|
||||||
E2F2 GIVAYF - convert (A,Y) to FP
|
E2F2 GIVAYF - convert (A,Y) to FP
|
||||||
@ -177,15 +243,16 @@ F941 PRINTAX - print AX registers in hex
|
|||||||
F948 PRBLNK - print 3 spaces
|
F948 PRBLNK - print 3 spaces
|
||||||
F94A PRBL2 - print X blank spaces
|
F94A PRBL2 - print X blank spaces
|
||||||
|
|
||||||
FAA6 reboot DOS
|
FAA6 PWRUP - reboot
|
||||||
FAFF 0 = Autostart ROM, 1 = Old Monitor
|
FAFF 0 = Autostart ROM, 1 = Old Monitor
|
||||||
|
|
||||||
FB1E PREAD - read game paddle
|
FB1E PREAD - read game paddle
|
||||||
FB2F initialise text screen
|
FB2F INIT - initialise text screen
|
||||||
FB39 text mode - SETTXT
|
FB39 text mode - SETTXT
|
||||||
FB40 SETGR
|
FB40 SETGR
|
||||||
FB5B TABV - monitor tab routine
|
FB5B TABV - monitor tab routine
|
||||||
FB6F set powerup checksum
|
FB6F SETPWRC - set powerup checksum
|
||||||
|
FBB3 VERSION - monitor ROM ID byte
|
||||||
FBC1 BASCALC - calculate video address
|
FBC1 BASCALC - calculate video address
|
||||||
FBDD BELL1 - beep speaker
|
FBDD BELL1 - beep speaker
|
||||||
FBF4 CURSRIT - move cursor right
|
FBF4 CURSRIT - move cursor right
|
||||||
@ -193,6 +260,7 @@ FBF4 CURSRIT - move cursor right
|
|||||||
FC10 CURSLFT - move cursor left
|
FC10 CURSLFT - move cursor left
|
||||||
FC1A CURSUP - move cursor up
|
FC1A CURSUP - move cursor up
|
||||||
FC22 VTAB
|
FC22 VTAB
|
||||||
|
FC24 VTABZ
|
||||||
FC42 CLREOP - clear to end of page
|
FC42 CLREOP - clear to end of page
|
||||||
FC58 HOME - clear screen
|
FC58 HOME - clear screen
|
||||||
FC62 CR
|
FC62 CR
|
||||||
@ -215,12 +283,13 @@ FDE3 PRHEX - print a hex digit
|
|||||||
FDED COUT - print a character (in Acc)
|
FDED COUT - print a character (in Acc)
|
||||||
FDF0 COUT1 - print character to screen
|
FDF0 COUT1 - print character to screen
|
||||||
|
|
||||||
FE2C move a block of memory
|
FE1F IDROUTINE - detect //gs
|
||||||
|
FE2C MOVE - move a block of memory
|
||||||
FE80 SETINV - set inverse mode
|
FE80 SETINV - set inverse mode
|
||||||
FE84 SETNORM - set normal mode
|
FE84 SETNORM - set normal mode
|
||||||
FE89 disconnect DOS from I/O links
|
FE89 SETKBD - disconnect DOS from I/O links
|
||||||
FE8B INPORT
|
FE8B INPORT
|
||||||
FE93 disconnect DOS from I/O links
|
FE93 SETVID - disconnect DOS from I/O links
|
||||||
FE95 OUTPORT
|
FE95 OUTPORT
|
||||||
FECD WRITE
|
FECD WRITE
|
||||||
FEFD READ
|
FEFD READ
|
||||||
@ -231,6 +300,14 @@ FF3A BELL
|
|||||||
FF3F IOREST - restore all registers
|
FF3F IOREST - restore all registers
|
||||||
FF4A IOSAVE - save all registers
|
FF4A IOSAVE - save all registers
|
||||||
FF58 RTS - jump to <address on stack> + 1
|
FF58 RTS - jump to <address on stack> + 1
|
||||||
FF59 Monitor cold entry point
|
FF59 MON - Monitor cold entry point (w/BELL)
|
||||||
|
FF69 MONZ - Monitor entry point from BASIC (CALL -151)
|
||||||
FFA7 GETNUM - move num to A2L.A2H
|
FFA7 GETNUM - move num to A2L.A2H
|
||||||
FFC7 ZMODE - monitor get ASCII return
|
FFC7 ZMODE - monitor get ASCII return
|
||||||
|
|
||||||
|
FFFA NMI_VECTOR
|
||||||
|
FFFB NMI_VECTOR
|
||||||
|
FFFC RESET_VECTOR
|
||||||
|
FFFD RESET_VECTOR
|
||||||
|
FFFE IRQ_VECTOR
|
||||||
|
FFFF IRQ_VECTOR
|
||||||
|
@ -139,7 +139,7 @@ public class AppleworksWPFile extends AbstractFile
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.printf ("Unknown value in %s: %02X %02X%n", name, b1, b2);
|
System.out.printf ("Unknown value in %s: %02X %02X%n", getName (), b1, b2);
|
||||||
}
|
}
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
|
@ -26,23 +26,28 @@ class CPMCatalogSector extends AbstractSector
|
|||||||
|
|
||||||
for (int i = 0; i <= 255; i += CATALOG_ENTRY_SIZE)
|
for (int i = 0; i <= 255; i += CATALOG_ENTRY_SIZE)
|
||||||
{
|
{
|
||||||
if (buffer[i] == (byte) 0xE5)
|
if (buffer[i] == (byte) 0xE5 && buffer[i + 1] == (byte) 0xE5)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int userNumber = buffer[i] & 0xFF;
|
||||||
|
if (userNumber > 31 && userNumber != (byte) 0xE5)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
boolean readOnly = (buffer[i + 9] & 0x80) != 0;
|
boolean readOnly = (buffer[i + 9] & 0x80) != 0;
|
||||||
boolean systemFile = (buffer[i + 10] & 0x80) != 0;
|
boolean systemFile = (buffer[i + 10] & 0x80) != 0;
|
||||||
|
boolean unknown = (buffer[i + 11] & 0x80) != 0;
|
||||||
String type;
|
String type;
|
||||||
String extra;
|
String extra;
|
||||||
|
|
||||||
if (readOnly || systemFile)
|
if (readOnly || systemFile || unknown)
|
||||||
{
|
{
|
||||||
byte[] typeBuffer = new byte[3];
|
byte[] typeBuffer = new byte[3];
|
||||||
typeBuffer[0] = (byte) (buffer[i + 9] & 0x7F);
|
typeBuffer[0] = (byte) (buffer[i + 9] & 0x7F);
|
||||||
typeBuffer[1] = (byte) (buffer[i + 10] & 0x7F);
|
typeBuffer[1] = (byte) (buffer[i + 10] & 0x7F);
|
||||||
typeBuffer[2] = buffer[i + 11];
|
typeBuffer[2] = (byte) (buffer[i + 11] & 0x7F);
|
||||||
type = new String (typeBuffer).trim ();
|
type = new String (typeBuffer).trim ();
|
||||||
extra = String.format (" (%s%s)", readOnly ? "read only" : "",
|
extra = String.format (" (%s%s%s)", readOnly ? "read only" : "",
|
||||||
systemFile ? "system file" : "");
|
systemFile ? "system file" : "", unknown ? "unknown" : "");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -50,8 +55,14 @@ class CPMCatalogSector extends AbstractSector
|
|||||||
extra = "";
|
extra = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
addText (text, buffer, i, 1, "User number");
|
if (buffer[i] == (byte) 0xE5)
|
||||||
addText (text, buffer, i + 1, 4, "File name : " + new String (buffer, i + 1, 8));
|
addText (text, buffer, i, 1, "Deleted file?");
|
||||||
|
else
|
||||||
|
addText (text, buffer, i, 1, "User number");
|
||||||
|
if (buffer[i + 1] == 0)
|
||||||
|
addText (text, buffer, i + 1, 4, "File name : ");
|
||||||
|
else
|
||||||
|
addText (text, buffer, i + 1, 4, "File name : " + new String (buffer, i + 1, 8));
|
||||||
addText (text, buffer, i + 5, 4, "");
|
addText (text, buffer, i + 5, 4, "");
|
||||||
addText (text, buffer, i + 9, 3, "File type : " + type + extra);
|
addText (text, buffer, i + 9, 3, "File type : " + type + extra);
|
||||||
addText (text, buffer, i + 12, 1, "Extent counter LO");
|
addText (text, buffer, i + 12, 1, "Extent counter LO");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.bytezone.diskbrowser.cpm;
|
package com.bytezone.diskbrowser.cpm;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.tree.DefaultMutableTreeNode;
|
import javax.swing.tree.DefaultMutableTreeNode;
|
||||||
@ -13,11 +14,15 @@ import com.bytezone.diskbrowser.disk.Disk;
|
|||||||
import com.bytezone.diskbrowser.disk.DiskAddress;
|
import com.bytezone.diskbrowser.disk.DiskAddress;
|
||||||
import com.bytezone.diskbrowser.disk.SectorType;
|
import com.bytezone.diskbrowser.disk.SectorType;
|
||||||
import com.bytezone.diskbrowser.gui.DataSource;
|
import com.bytezone.diskbrowser.gui.DataSource;
|
||||||
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
|
|
||||||
|
// https://www.retrotechnology.com/dri/howto_cpm.html
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class CPMDisk extends AbstractFormattedDisk
|
public class CPMDisk extends AbstractFormattedDisk
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
private static final int EMPTY_BYTE_VALUE = 0xE5;
|
||||||
|
|
||||||
private final Color green = new Color (0, 200, 0);
|
private final Color green = new Color (0, 200, 0);
|
||||||
|
|
||||||
public final SectorType catalogSector = new SectorType ("Catalog", green);
|
public final SectorType catalogSector = new SectorType ("Catalog", green);
|
||||||
@ -50,7 +55,7 @@ public class CPMDisk extends AbstractFormattedDisk
|
|||||||
sectorTypesList.add (macSector);
|
sectorTypesList.add (macSector);
|
||||||
sectorTypesList.add (otherSector);
|
sectorTypesList.add (otherSector);
|
||||||
|
|
||||||
setEmptyByte ((byte) 0xE5);
|
setEmptyByte ((byte) EMPTY_BYTE_VALUE);
|
||||||
|
|
||||||
// search for the version string
|
// search for the version string
|
||||||
for (int i = 8; i >= 4; i -= 2)
|
for (int i = 8; i >= 4; i -= 2)
|
||||||
@ -74,22 +79,28 @@ public class CPMDisk extends AbstractFormattedDisk
|
|||||||
|
|
||||||
sectorTypes[da.getBlockNo ()] = catalogSector;
|
sectorTypes[da.getBlockNo ()] = catalogSector;
|
||||||
byte[] buffer = disk.readBlock (da);
|
byte[] buffer = disk.readBlock (da);
|
||||||
|
|
||||||
int b1 = buffer[0] & 0xFF;
|
int b1 = buffer[0] & 0xFF;
|
||||||
int b2 = buffer[1] & 0xFF;
|
int b2 = buffer[1] & 0xFF;
|
||||||
if (b1 == 0xE5)
|
|
||||||
|
if (b1 == EMPTY_BYTE_VALUE && (b2 == EMPTY_BYTE_VALUE || b2 == 0))
|
||||||
continue;
|
continue;
|
||||||
if (b1 > 31)
|
|
||||||
|
if (b1 > 31 && b1 != EMPTY_BYTE_VALUE)
|
||||||
break;
|
break;
|
||||||
if (b2 < 32 || (b2 > 126 && b2 != 0xE5))
|
|
||||||
|
if (b2 <= 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (int i = 0; i < buffer.length; i += 32)
|
for (int i = 0; i < buffer.length; i += 32)
|
||||||
{
|
{
|
||||||
b1 = buffer[i] & 0xFF;
|
b1 = buffer[i] & 0xFF;
|
||||||
b2 = buffer[i + 1] & 0xFF;
|
b2 = buffer[i + 1] & 0xFF;
|
||||||
if (b1 == 0xE5)
|
|
||||||
break;
|
if (b1 == EMPTY_BYTE_VALUE) // deleted file??
|
||||||
if (b2 < 32 || (b2 > 126 && b2 != 0xE5))
|
continue;
|
||||||
|
|
||||||
|
if (b2 <= 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DirectoryEntry entry = new DirectoryEntry (this, buffer, i);
|
DirectoryEntry entry = new DirectoryEntry (this, buffer, i);
|
||||||
@ -111,9 +122,6 @@ public class CPMDisk extends AbstractFormattedDisk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// root.setUserObject (getCatalog ()); // override the disk's default display
|
|
||||||
// makeNodeVisible (rootNode.getFirstLeaf ());
|
|
||||||
|
|
||||||
volumeNode.setUserObject (getCatalog ());
|
volumeNode.setUserObject (getCatalog ());
|
||||||
makeNodeVisible (volumeNode.getFirstLeaf ());
|
makeNodeVisible (volumeNode.getFirstLeaf ());
|
||||||
}
|
}
|
||||||
@ -147,6 +155,7 @@ public class CPMDisk extends AbstractFormattedDisk
|
|||||||
{
|
{
|
||||||
if (fileEntries.size () > 0 && fileEntries.size () > fileNo)
|
if (fileEntries.size () > 0 && fileEntries.size () > fileNo)
|
||||||
return fileEntries.get (fileNo).getSectors ();
|
return fileEntries.get (fileNo).getSectors ();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,19 +189,17 @@ public class CPMDisk extends AbstractFormattedDisk
|
|||||||
public AppleFileSource getCatalog ()
|
public AppleFileSource getCatalog ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
String newLine = String.format ("%n");
|
String line = "---- --------- --- - - -- -- -- -- ----------------------------"
|
||||||
String line =
|
+ "-------------------\n";
|
||||||
"---- --------- --- - - -- -- -- -- ----------------------------"
|
|
||||||
+ "-------------------" + newLine;
|
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
text.append (String.format ("File : %s%n%n", getDisplayPath ()));
|
text.append (String.format ("File : %s%n%n", getDisplayPath ()));
|
||||||
text.append ("User Name Typ R S Ex S2 S1 RC Blocks" + newLine);
|
text.append ("User Name Typ R S Ex S2 S1 RC Blocks\n");
|
||||||
text.append (line);
|
text.append (line);
|
||||||
|
|
||||||
for (AppleFileSource entry : fileEntries)
|
for (AppleFileSource entry : fileEntries)
|
||||||
{
|
{
|
||||||
text.append (((DirectoryEntry) entry).line ());
|
text.append (((DirectoryEntry) entry).line ());
|
||||||
text.append (newLine);
|
text.append ("\n");
|
||||||
}
|
}
|
||||||
text.append (line);
|
text.append (line);
|
||||||
if (version != 0)
|
if (version != 0)
|
||||||
@ -204,6 +211,64 @@ public class CPMDisk extends AbstractFormattedDisk
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public static boolean isCorrectFormat (AppleDisk disk)
|
public static boolean isCorrectFormat (AppleDisk disk)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
boolean debug = false;
|
||||||
|
|
||||||
|
disk.setInterleave (3);
|
||||||
|
|
||||||
|
// collect catalog sectors
|
||||||
|
List<DiskAddress> catalog = new ArrayList<> ();
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
catalog.add (disk.getDiskAddress (3, i));
|
||||||
|
byte[] buffer = disk.readBlocks (catalog);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
System.out.println (HexFormatter.format (buffer));
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
int start = i * 1024;
|
||||||
|
int end = start + 1024;
|
||||||
|
|
||||||
|
for (int ptr = start; ptr < end; ptr += 32)
|
||||||
|
{
|
||||||
|
if (buffer[ptr] == (byte) EMPTY_BYTE_VALUE)
|
||||||
|
{
|
||||||
|
if (buffer[ptr + 1] == (byte) EMPTY_BYTE_VALUE //
|
||||||
|
|| buffer[ptr + 1] == 0) // finished this block
|
||||||
|
break;
|
||||||
|
continue; // deleted file?
|
||||||
|
}
|
||||||
|
|
||||||
|
int userNo = buffer[ptr] & 0xFF;
|
||||||
|
if (userNo > 31)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int j = 1; j < 12; j++)
|
||||||
|
{
|
||||||
|
int ch = buffer[ptr + j] & 0x7F; // remove flag
|
||||||
|
if (ch < 32 || ch > 126) // invalid ascii
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
String fileName = new String (buffer, ptr + 1, 8);
|
||||||
|
String fileType = new String (buffer, ptr + 9, 3);
|
||||||
|
System.out.printf ("%2d %s %s%n", userNo, fileName, fileType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
System.out.println ("CP/M disk");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private static boolean isCorrectFormat2 (AppleDisk disk)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
disk.setInterleave (3);
|
disk.setInterleave (3);
|
||||||
|
|
||||||
@ -222,26 +287,60 @@ public class CPMDisk extends AbstractFormattedDisk
|
|||||||
for (int sector = 0; sector < 8; sector++)
|
for (int sector = 0; sector < 8; sector++)
|
||||||
{
|
{
|
||||||
byte[] buffer = disk.readBlock (3, sector);
|
byte[] buffer = disk.readBlock (3, sector);
|
||||||
|
System.out.println (HexFormatter.format (buffer));
|
||||||
|
|
||||||
// check if entire sector is empty (everything == 0xE5)
|
// check if entire sector is empty (everything == 0xE5)
|
||||||
if (bufferContainsAll (buffer, (byte) 0xE5))
|
if (bufferContainsAll (buffer, (byte) EMPTY_BYTE_VALUE))
|
||||||
|
break;
|
||||||
|
|
||||||
|
int b1 = buffer[0] & 0xFF;
|
||||||
|
int b2 = buffer[1] & 0xFF;
|
||||||
|
|
||||||
|
if (b1 == EMPTY_BYTE_VALUE && (b2 == EMPTY_BYTE_VALUE || b2 == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (b1 > 31 && b1 != EMPTY_BYTE_VALUE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (b2 < 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (int i = 0; i < buffer.length; i += 32)
|
for (int i = 0; i < buffer.length; i += 32)
|
||||||
{
|
{
|
||||||
int val = buffer[i] & 0xFF;
|
b1 = buffer[i] & 0xFF;
|
||||||
if (val == 0xE5)
|
b2 = buffer[i + 1] & 0xFF;
|
||||||
break;
|
|
||||||
|
|
||||||
if (val > 31)
|
if (b1 == EMPTY_BYTE_VALUE) // deleted file??
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (b2 < 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (int j = 1; j <= 8; j++)
|
// int val = buffer[i] & 0xFF;
|
||||||
{
|
// if (val == EMPTY_BYTE_VALUE)
|
||||||
val = buffer[i + j] & 0xFF;
|
// {
|
||||||
if (val < 32 || (val > 126 && val != 0xE5))
|
// if (debug)
|
||||||
return false;
|
// System.out.println ("empty value found - deleted file?");
|
||||||
}
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (val > 31)
|
||||||
|
// {
|
||||||
|
// if (debug)
|
||||||
|
// System.out.println ("val > 31");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (int j = 1; j <= 8; j++)
|
||||||
|
// {
|
||||||
|
// val = buffer[i + j] & 0xFF;
|
||||||
|
// if (val < 32 || (val > 126 && val != EMPTY_BYTE_VALUE))
|
||||||
|
// {
|
||||||
|
// if (debug)
|
||||||
|
// System.out.println ("val < 32 || val > 126");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
||||||
|
import com.bytezone.diskbrowser.applefile.CPMBasicFile;
|
||||||
import com.bytezone.diskbrowser.applefile.CPMTextFile;
|
import com.bytezone.diskbrowser.applefile.CPMTextFile;
|
||||||
import com.bytezone.diskbrowser.applefile.DefaultAppleFile;
|
import com.bytezone.diskbrowser.applefile.DefaultAppleFile;
|
||||||
import com.bytezone.diskbrowser.disk.AppleDiskAddress;
|
import com.bytezone.diskbrowser.disk.AppleDiskAddress;
|
||||||
@ -54,7 +55,11 @@ class DirectoryEntry implements AppleFileSource
|
|||||||
type = new String (typeBuffer).trim ();
|
type = new String (typeBuffer).trim ();
|
||||||
|
|
||||||
userNumber = buffer[offset] & 0xFF;
|
userNumber = buffer[offset] & 0xFF;
|
||||||
name = new String (buffer, offset + 1, 8).trim ();
|
if (userNumber == 0xE5 && buffer[offset + 1] == 0)
|
||||||
|
name = "";
|
||||||
|
else
|
||||||
|
name = new String (buffer, offset + 1, 8).trim ();
|
||||||
|
|
||||||
extent = buffer[offset + 12] & 0xFF;
|
extent = buffer[offset + 12] & 0xFF;
|
||||||
s2 = buffer[offset + 13] & 0xFF;
|
s2 = buffer[offset + 13] & 0xFF;
|
||||||
s1 = buffer[offset + 14] & 0xFF;
|
s1 = buffer[offset + 14] & 0xFF;
|
||||||
@ -77,9 +82,6 @@ class DirectoryEntry implements AppleFileSource
|
|||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
blocks.add (new AppleDiskAddress (disk, blockNumber + i));
|
blocks.add (new AppleDiskAddress (disk, blockNumber + i));
|
||||||
}
|
}
|
||||||
// if (name.equals ("cp/m"))
|
|
||||||
// for (DiskAddress da : blocks)
|
|
||||||
// System.out.println (da);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -123,6 +125,7 @@ class DirectoryEntry implements AppleFileSource
|
|||||||
for (DiskAddress sector : blocks)
|
for (DiskAddress sector : blocks)
|
||||||
if (sector.matches (da))
|
if (sector.matches (da))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,9 +139,8 @@ class DirectoryEntry implements AppleFileSource
|
|||||||
char ro = readOnly ? '*' : ' ';
|
char ro = readOnly ? '*' : ' ';
|
||||||
char sf = systemFile ? '*' : ' ';
|
char sf = systemFile ? '*' : ' ';
|
||||||
|
|
||||||
String text =
|
String text = String.format ("%3d %-8s %-3s %s %s %02X %02X %02X %02X %s",
|
||||||
String.format ("%3d %-8s %-3s %s %s %02X %02X %02X %02X %s",
|
userNumber, name, type, ro, sf, extent, s2, s1, recordsUsed, bytes);
|
||||||
userNumber, name, type, ro, sf, extent, s2, s1, recordsUsed, bytes);
|
|
||||||
for (DirectoryEntry entry : entries)
|
for (DirectoryEntry entry : entries)
|
||||||
text = text + "\n" + entry.line ();
|
text = text + "\n" + entry.line ();
|
||||||
|
|
||||||
@ -210,23 +212,18 @@ class DirectoryEntry implements AppleFileSource
|
|||||||
byte[] exactBuffer = new byte[len];
|
byte[] exactBuffer = new byte[len];
|
||||||
System.arraycopy (buffer, 0, exactBuffer, 0, len);
|
System.arraycopy (buffer, 0, exactBuffer, 0, len);
|
||||||
|
|
||||||
int max = Math.min (256, exactBuffer.length);
|
|
||||||
int count = 0;
|
|
||||||
for (int i = 1; i < max; i++)
|
|
||||||
{
|
|
||||||
if (exactBuffer[i - 1] == 0x0D && exactBuffer[i] == 0x0A)
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("COM".equals (type))
|
if ("COM".equals (type))
|
||||||
appleFile = new DefaultAppleFile (name, exactBuffer, "COM File");
|
appleFile = new DefaultAppleFile (name, exactBuffer, "COM File");
|
||||||
else if ("DVR".equals (type))
|
else if ("DVR".equals (type))
|
||||||
appleFile = new DefaultAppleFile (name, exactBuffer, "DVR File");
|
appleFile = new DefaultAppleFile (name, exactBuffer, "DVR File");
|
||||||
else if ("ASM".equals (type) || "DOC".equals (type) || "TXT".equals (type)
|
else if ("ASM".equals (type) || "DOC".equals (type) || "COB".equals (type)
|
||||||
|| count > 2)
|
|| "HLP".equals (type) || "TXT".equals (type) || "LET".equals (type) || "ALX".equals (type)
|
||||||
|
|| "SRC".equals (type) || "H".equals (type) || exactBuffer[len - 1] == 0x1A)
|
||||||
appleFile = new CPMTextFile (name, exactBuffer);
|
appleFile = new CPMTextFile (name, exactBuffer);
|
||||||
|
else if ("BAS".equals (type))
|
||||||
|
appleFile = new CPMBasicFile (name, exactBuffer);
|
||||||
else
|
else
|
||||||
appleFile = new DefaultAppleFile (name, exactBuffer, "CPM File : " + type);
|
appleFile = new DefaultAppleFile (name, exactBuffer, "CPM File : " + name + "." + type);
|
||||||
|
|
||||||
return appleFile;
|
return appleFile;
|
||||||
}
|
}
|
||||||
|
@ -206,8 +206,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
|
|||||||
|
|
||||||
DefaultMutableTreeNode root = getCatalogTreeRoot ();
|
DefaultMutableTreeNode root = getCatalogTreeRoot ();
|
||||||
if (root.getUserObject () == null)
|
if (root.getUserObject () == null)
|
||||||
root.setUserObject (
|
root.setUserObject (new DefaultAppleFileSource (getName (), disk.toString (), this));
|
||||||
new DefaultAppleFileSource (getName (), disk.toString (), this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -234,15 +233,15 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
|
|||||||
public String getDisplayPath ()
|
public String getDisplayPath ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
// if (originalPath != null)
|
|
||||||
// return originalPath.toString ();
|
|
||||||
|
|
||||||
String home = System.getProperty ("user.home");
|
String home = System.getProperty ("user.home");
|
||||||
|
|
||||||
String path = originalPath != null ? originalPath.toString ()
|
String path =
|
||||||
: disk.getFile ().getAbsolutePath ();
|
originalPath != null ? originalPath.toString () : disk.getFile ().getAbsolutePath ();
|
||||||
if (path.startsWith (home))
|
|
||||||
return "~" + path.substring (home.length ());
|
int pos = path.indexOf (home);
|
||||||
|
|
||||||
|
if (pos == 0 || (path.startsWith ("/Volumes/") && pos > 0))
|
||||||
|
return "~" + path.substring (home.length () + pos);
|
||||||
|
|
||||||
return disk.getFile ().getAbsolutePath ();
|
return disk.getFile ().getAbsolutePath ();
|
||||||
}
|
}
|
||||||
@ -327,8 +326,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
|
|||||||
if (children != null)
|
if (children != null)
|
||||||
while (children.hasMoreElements ())
|
while (children.hasMoreElements ())
|
||||||
{
|
{
|
||||||
DefaultMutableTreeNode childNode =
|
DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) children.nextElement ();
|
||||||
(DefaultMutableTreeNode) children.nextElement ();
|
|
||||||
if (childNode.getUserObject ().toString ().indexOf (name) > 0)
|
if (childNode.getUserObject ().toString ().indexOf (name) > 0)
|
||||||
return childNode;
|
return childNode;
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,12 @@ import javax.swing.JPanel;
|
|||||||
import com.bytezone.diskbrowser.applefile.AssemblerProgram;
|
import com.bytezone.diskbrowser.applefile.AssemblerProgram;
|
||||||
import com.bytezone.diskbrowser.gui.DataSource;
|
import com.bytezone.diskbrowser.gui.DataSource;
|
||||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public abstract class AbstractSector implements DataSource
|
public abstract class AbstractSector implements DataSource
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static String newLine = String.format ("%n");
|
|
||||||
private static String newLine2 = newLine + newLine;
|
|
||||||
|
|
||||||
final public byte[] buffer;
|
final public byte[] buffer;
|
||||||
protected Disk disk;
|
protected Disk disk;
|
||||||
protected DiskAddress diskAddress;
|
protected DiskAddress diskAddress;
|
||||||
@ -90,10 +88,11 @@ public abstract class AbstractSector implements DataSource
|
|||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
text.append (title + newLine2);
|
text.append (title + "\n\n");
|
||||||
text.append ("Offset Value Description" + newLine);
|
text.append ("Offset Value Description\n");
|
||||||
text.append ("======= =========== "
|
text.append ("======= =========== "
|
||||||
+ "===============================================================" + newLine);
|
+ "===============================================================\n");
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,14 +142,13 @@ public abstract class AbstractSector implements DataSource
|
|||||||
String desc)
|
String desc)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (size == 1)
|
desc += switch (size)
|
||||||
desc += " (" + (b[offset] & 0xFF) + ")";
|
{
|
||||||
else if (size == 2)
|
case 1 -> " (" + (b[offset] & 0xFF) + ")";
|
||||||
desc +=
|
case 2 -> String.format (" (%,d)", Utility.getShort (b, offset));
|
||||||
String.format (" (%,d)", ((b[offset + 1] & 0xFF) * 256 + (b[offset] & 0xFF)));
|
case 3 -> String.format (" (%,d)", Utility.readTriple (b, offset));
|
||||||
else if (size == 3)
|
default -> "";
|
||||||
desc += String.format (" (%,d)", ((b[offset + 2] & 0xFF) * 65536)
|
};
|
||||||
+ ((b[offset + 1] & 0xFF) * 256) + (b[offset] & 0xFF));
|
|
||||||
|
|
||||||
addText (text, b, offset, size, desc);
|
addText (text, b, offset, size, desc);
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ import java.util.zip.Checksum;
|
|||||||
import com.bytezone.diskbrowser.nib.NibFile;
|
import com.bytezone.diskbrowser.nib.NibFile;
|
||||||
import com.bytezone.diskbrowser.nib.V2dFile;
|
import com.bytezone.diskbrowser.nib.V2dFile;
|
||||||
import com.bytezone.diskbrowser.nib.WozFile;
|
import com.bytezone.diskbrowser.nib.WozFile;
|
||||||
import com.bytezone.diskbrowser.utilities.Binary2;
|
import com.bytezone.diskbrowser.nufx.Binary2;
|
||||||
|
import com.bytezone.diskbrowser.nufx.NuFX;
|
||||||
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
||||||
import com.bytezone.diskbrowser.utilities.NuFX;
|
|
||||||
import com.bytezone.diskbrowser.utilities.Utility;
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
@ -48,11 +48,11 @@ public class AppleDisk implements Disk
|
|||||||
|
|
||||||
private int interleave = 0;
|
private int interleave = 0;
|
||||||
private static int[][] interleaveSector = //
|
private static int[][] interleaveSector = //
|
||||||
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, //
|
||||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }, // None
|
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }, // None
|
||||||
{ 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15 }, // Prodos/Pascal
|
{ 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15 }, // Prodos/Pascal
|
||||||
{ 0, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 15 }, // Infocom
|
{ 0, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 15 }, // Infocom
|
||||||
{ 0, 6, 12, 3, 9, 15, 14, 5, 11, 2, 8, 7, 13, 4, 10, 1 } }; // CPM
|
{ 0, 6, 12, 3, 9, 15, 14, 5, 11, 2, 8, 7, 13, 4, 10, 1 } }; // CPM
|
||||||
|
|
||||||
// Physical disk interleave:
|
// Physical disk interleave:
|
||||||
// Info from http://www.applelogic.org/TheAppleIIEGettingStarted.html
|
// Info from http://www.applelogic.org/TheAppleIIEGettingStarted.html
|
||||||
@ -101,8 +101,7 @@ public class AppleDisk implements Disk
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public AppleDisk (File file, int tracks, int sectors, int skip)
|
public AppleDisk (File file, int tracks, int sectors, int skip) throws FileFormatException
|
||||||
throws FileFormatException
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
assert (file.exists ()) : "No such path :" + file.getAbsolutePath ();
|
assert (file.exists ()) : "No such path :" + file.getAbsolutePath ();
|
||||||
@ -158,7 +157,7 @@ public class AppleDisk implements Disk
|
|||||||
tracks = blocks / 8; // change parameter!
|
tracks = blocks / 8; // change parameter!
|
||||||
sectors = 8; // change parameter!
|
sectors = 8; // change parameter!
|
||||||
}
|
}
|
||||||
else if (suffix.equalsIgnoreCase ("HDV")
|
else if (suffix.equalsIgnoreCase ("HDV") //
|
||||||
|| (suffix.equalsIgnoreCase ("po") && tracks > 50)) // ULTIMATE APPLE1 CFFA 3.5.po
|
|| (suffix.equalsIgnoreCase ("po") && tracks > 50)) // ULTIMATE APPLE1 CFFA 3.5.po
|
||||||
{
|
{
|
||||||
//this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8
|
//this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8
|
||||||
@ -166,7 +165,7 @@ public class AppleDisk implements Disk
|
|||||||
this.sectorSize = 512;
|
this.sectorSize = 512;
|
||||||
this.trackSize = sectors * sectorSize;
|
this.trackSize = sectors * sectorSize;
|
||||||
}
|
}
|
||||||
else if (file.length () == 143360 && tracks == 256 && sectors == 8) // wiz4
|
else if (file.length () == 143360 && tracks == 256 && sectors == 8) // wiz4 or wiz5
|
||||||
{
|
{
|
||||||
this.blocks = tracks * sectors;
|
this.blocks = tracks * sectors;
|
||||||
this.sectorSize = 512;
|
this.sectorSize = 512;
|
||||||
@ -363,7 +362,6 @@ public class AppleDisk implements Disk
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.dosVersion = version;
|
this.dosVersion = version;
|
||||||
// System.out.printf ("DOS version %02X%n", version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -469,6 +467,7 @@ public class AppleDisk implements Disk
|
|||||||
readBuffer (da, buffer, ptr);
|
readBuffer (da, buffer, ptr);
|
||||||
ptr += sectorSize;
|
ptr += sectorSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,8 +556,7 @@ public class AppleDisk implements Disk
|
|||||||
{
|
{
|
||||||
if (!isValidAddress (block))
|
if (!isValidAddress (block))
|
||||||
{
|
{
|
||||||
System.out.printf ("getDiskAddress: Invalid block : %d of %d%n", block,
|
System.out.printf ("getDiskAddress: Invalid block : %d of %d%n", block, this.blocks);
|
||||||
this.blocks);
|
|
||||||
return null;
|
return null;
|
||||||
// return new AppleDiskAddress (this, 0); // this was looping 26/07/2016
|
// return new AppleDiskAddress (this, 0); // this was looping 26/07/2016
|
||||||
}
|
}
|
||||||
@ -624,10 +622,9 @@ public class AppleDisk implements Disk
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
assert da.getDisk () == this : "Disk address not applicable to this disk";
|
assert da.getDisk () == this : "Disk address not applicable to this disk";
|
||||||
assert sectorSize == SECTOR_SIZE
|
assert sectorSize == SECTOR_SIZE || sectorSize == BLOCK_SIZE : "Invalid sector size : "
|
||||||
|| sectorSize == BLOCK_SIZE : "Invalid sector size : " + sectorSize;
|
+ sectorSize;
|
||||||
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : "
|
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : " + interleave;
|
||||||
+ interleave;
|
|
||||||
|
|
||||||
if (sectorSize == SECTOR_SIZE)
|
if (sectorSize == SECTOR_SIZE)
|
||||||
{
|
{
|
||||||
@ -640,8 +637,7 @@ public class AppleDisk implements Disk
|
|||||||
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, SECTOR_SIZE);
|
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, SECTOR_SIZE);
|
||||||
|
|
||||||
diskOffset = getBufferOffset (da, 1);
|
diskOffset = getBufferOffset (da, 1);
|
||||||
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + SECTOR_SIZE,
|
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + SECTOR_SIZE, SECTOR_SIZE);
|
||||||
SECTOR_SIZE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,10 +646,9 @@ public class AppleDisk implements Disk
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
assert da.getDisk () == this : "Disk address not applicable to this disk";
|
assert da.getDisk () == this : "Disk address not applicable to this disk";
|
||||||
assert sectorSize == SECTOR_SIZE
|
assert sectorSize == SECTOR_SIZE || sectorSize == BLOCK_SIZE : "Invalid sector size : "
|
||||||
|| sectorSize == BLOCK_SIZE : "Invalid sector size : " + sectorSize;
|
+ sectorSize;
|
||||||
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : "
|
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : " + interleave;
|
||||||
+ interleave;
|
|
||||||
|
|
||||||
if (sectorSize == SECTOR_SIZE)
|
if (sectorSize == SECTOR_SIZE)
|
||||||
{
|
{
|
||||||
@ -670,6 +665,13 @@ public class AppleDisk implements Disk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public byte[] getBuffer ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
return diskBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private int getBufferOffset (DiskAddress da)
|
private int getBufferOffset (DiskAddress da)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -731,12 +733,8 @@ public class AppleDisk implements Disk
|
|||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
String path = file.getAbsolutePath ();
|
text.append (
|
||||||
String home = System.getProperty ("user.home");
|
String.format ("Path ......... %s%n", Utility.getShortPath (file.getAbsolutePath ())));
|
||||||
if (path.startsWith (home))
|
|
||||||
path = "~" + path.substring (home.length ());
|
|
||||||
|
|
||||||
text.append (String.format ("Path ......... %s%n", path));
|
|
||||||
text.append (String.format ("File name .... %s%n", file.getName ()));
|
text.append (String.format ("File name .... %s%n", file.getName ()));
|
||||||
text.append (String.format ("File size .... %,d%n", file.length ()));
|
text.append (String.format ("File size .... %,d%n", file.length ()));
|
||||||
text.append (String.format ("Tracks ....... %d%n", tracks));
|
text.append (String.format ("Tracks ....... %d%n", tracks));
|
||||||
|
@ -49,8 +49,8 @@ public class DefaultAppleFileSource implements AppleFileSource
|
|||||||
{
|
{
|
||||||
this (title, file, owner);
|
this (title, file, owner);
|
||||||
this.blocks = blocks;
|
this.blocks = blocks;
|
||||||
if (file instanceof DefaultDataSource)
|
if (file instanceof DefaultDataSource dds)
|
||||||
((DefaultDataSource) file).buffer = owner.getDisk ().readBlocks (blocks);
|
dds.buffer = owner.getDisk ().readBlocks (blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -58,8 +58,8 @@ public class DefaultAppleFileSource implements AppleFileSource
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.blocks = blocks;
|
this.blocks = blocks;
|
||||||
if (file instanceof DefaultDataSource)
|
if (file instanceof DefaultDataSource dds)
|
||||||
((DefaultDataSource) file).buffer = owner.getDisk ().readBlocks (blocks);
|
dds.buffer = owner.getDisk ().readBlocks (blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.bytezone.diskbrowser.disk;
|
package com.bytezone.diskbrowser.disk;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -18,11 +19,12 @@ import com.bytezone.diskbrowser.infocom.InfocomDisk;
|
|||||||
import com.bytezone.diskbrowser.nib.NibFile;
|
import com.bytezone.diskbrowser.nib.NibFile;
|
||||||
import com.bytezone.diskbrowser.nib.V2dFile;
|
import com.bytezone.diskbrowser.nib.V2dFile;
|
||||||
import com.bytezone.diskbrowser.nib.WozFile;
|
import com.bytezone.diskbrowser.nib.WozFile;
|
||||||
|
import com.bytezone.diskbrowser.nufx.Binary2;
|
||||||
|
import com.bytezone.diskbrowser.nufx.NuFX;
|
||||||
import com.bytezone.diskbrowser.pascal.PascalDisk;
|
import com.bytezone.diskbrowser.pascal.PascalDisk;
|
||||||
import com.bytezone.diskbrowser.prodos.ProdosDisk;
|
import com.bytezone.diskbrowser.prodos.ProdosDisk;
|
||||||
import com.bytezone.diskbrowser.utilities.Binary2;
|
|
||||||
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
||||||
import com.bytezone.diskbrowser.utilities.NuFX;
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
import com.bytezone.diskbrowser.utilities.Utility;
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
import com.bytezone.diskbrowser.wizardry.Wizardry4BootDisk;
|
import com.bytezone.diskbrowser.wizardry.Wizardry4BootDisk;
|
||||||
import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk;
|
import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk;
|
||||||
@ -32,6 +34,7 @@ public class DiskFactory
|
|||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static boolean debug = false;
|
private static boolean debug = false;
|
||||||
|
|
||||||
private static final int DISK_800K = 819200;
|
private static final int DISK_800K = 819200;
|
||||||
private static final int DISK_143K = 143360;
|
private static final int DISK_143K = 143360;
|
||||||
private static final int DISK_116K = 116480;
|
private static final int DISK_116K = 116480;
|
||||||
@ -145,7 +148,7 @@ public class DiskFactory
|
|||||||
|
|
||||||
if ("sdk".equals (suffix) // NuFX disk
|
if ("sdk".equals (suffix) // NuFX disk
|
||||||
|| "shk".equals (suffix) // NuFX files or disk
|
|| "shk".equals (suffix) // NuFX files or disk
|
||||||
|| "bxy".equals (suffix)) // NuFX in Binary2
|
|| "bxy".equals (suffix)) // NuFX in Bin2
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println (" ** sdk/shk/bxy **");
|
System.out.println (" ** sdk/shk/bxy **");
|
||||||
@ -153,7 +156,11 @@ public class DiskFactory
|
|||||||
{
|
{
|
||||||
nuFX = new NuFX (file.toPath ());
|
nuFX = new NuFX (file.toPath ());
|
||||||
if (nuFX.getTotalDisks () == 0 && nuFX.getTotalFiles () == 0)
|
if (nuFX.getTotalDisks () == 0 && nuFX.getTotalFiles () == 0)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
System.out.println ("Empty NuFX file");
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] diskBuffer = nuFX.getDiskBuffer ();
|
byte[] diskBuffer = nuFX.getDiskBuffer ();
|
||||||
if (diskBuffer == null)
|
if (diskBuffer == null)
|
||||||
@ -176,14 +183,14 @@ public class DiskFactory
|
|||||||
else
|
else
|
||||||
System.out.println (e.getMessage ());
|
System.out.println (e.getMessage ());
|
||||||
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
|
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
|
||||||
// System.out.println (nuFX);
|
// System.out.println (nuFX);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ("bny".equals (suffix)) // Binary2 uncompressed files
|
else if ("bny".equals (suffix) || "bqy".equals (suffix)) // Binary2 uncompressed files
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println (" ** bny **");
|
System.out.println (" ** bny/bqy **");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
binary2 = new Binary2 (file.toPath ());
|
binary2 = new Binary2 (file.toPath ());
|
||||||
@ -201,13 +208,21 @@ public class DiskFactory
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// e.printStackTrace ();
|
// e.printStackTrace ();
|
||||||
System.out.println (e.getMessage ());
|
System.out.println (e.getMessage ());
|
||||||
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
|
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
|
||||||
// System.out.println (binary2);
|
// System.out.println (binary2);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ("bsq".equals (suffix))
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
System.out.println (" ** bsq **");
|
||||||
|
byte[] prefix = getPrefix (file);
|
||||||
|
System.out.println (HexFormatter.format (prefix));
|
||||||
|
String key = "FiLeStArTfIlEsTaRt";
|
||||||
|
}
|
||||||
|
|
||||||
FormattedDisk disk = null;
|
FormattedDisk disk = null;
|
||||||
FormattedDisk disk2 = null;
|
FormattedDisk disk2 = null;
|
||||||
@ -268,7 +283,7 @@ public class DiskFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.printf (" Checking po or dsk hard drive: %,d%n", file.length ());
|
System.out.printf ("Checking po or dsk hard drive: %,d%n", file.length ());
|
||||||
|
|
||||||
disk = checkHardDisk (file);
|
disk = checkHardDisk (file);
|
||||||
if (disk != null)
|
if (disk != null)
|
||||||
@ -335,9 +350,10 @@ public class DiskFactory
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println (" --> PRODOS hard disk");
|
System.out.println (" --> PRODOS hard disk");
|
||||||
return new ProdosDisk (disk800);
|
disk = new ProdosDisk (disk800);
|
||||||
}
|
}
|
||||||
disk = new DataDisk (disk800);
|
else
|
||||||
|
disk = new DataDisk (disk800);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -345,11 +361,15 @@ public class DiskFactory
|
|||||||
disk = checkDos (appleDisk256);
|
disk = checkDos (appleDisk256);
|
||||||
if (disk == null)
|
if (disk == null)
|
||||||
disk = checkProdos (new AppleDisk (wozFile, 35, 8));
|
disk = checkProdos (new AppleDisk (wozFile, 35, 8));
|
||||||
|
if (disk == null)
|
||||||
|
disk = checkPascalDisk (new AppleDisk (wozFile, 35, 8));
|
||||||
if (disk == null)
|
if (disk == null)
|
||||||
disk = new DataDisk (appleDisk256);
|
disk = new DataDisk (appleDisk256);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disk.setOriginalPath (originalPath); // allow Save converted disk...
|
||||||
|
|
||||||
return disk;
|
return disk;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -408,7 +428,7 @@ public class DiskFactory
|
|||||||
|
|
||||||
if (true)
|
if (true)
|
||||||
{
|
{
|
||||||
// long checksum = appleDisk256.getBootChecksum ();
|
// long checksum = appleDisk256.getBootChecksum ();
|
||||||
long checksum = 0;
|
long checksum = 0;
|
||||||
|
|
||||||
if (checksum == 227968344L) // empty boot sector
|
if (checksum == 227968344L) // empty boot sector
|
||||||
@ -433,7 +453,7 @@ public class DiskFactory
|
|||||||
if (debug)
|
if (debug)
|
||||||
System.out.println (" known DOS checksum : " + checksum);
|
System.out.println (" known DOS checksum : " + checksum);
|
||||||
disk = checkDos (appleDisk256);
|
disk = checkDos (appleDisk256);
|
||||||
// disk2 = checkProdos (appleDisk512); // no need for this
|
// disk2 = checkProdos (appleDisk512); // no need for this
|
||||||
if (disk2 != null && disk != null) // should be impossible
|
if (disk2 != null && disk != null) // should be impossible
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -479,11 +499,11 @@ public class DiskFactory
|
|||||||
else if (debug)
|
else if (debug)
|
||||||
System.out.println (" unknown checksum : " + checksum);
|
System.out.println (" unknown checksum : " + checksum);
|
||||||
|
|
||||||
// else if (checksum == 1212926910L || checksum == 1365043894L
|
// else if (checksum == 1212926910L || checksum == 1365043894L
|
||||||
// || checksum == 2128073918L)
|
// || checksum == 2128073918L)
|
||||||
// disk = checkCPMDisk (file);
|
// disk = checkCPMDisk (file);
|
||||||
|
|
||||||
// System.out.println (checksum);
|
// System.out.println (checksum);
|
||||||
|
|
||||||
if (disk != null)
|
if (disk != null)
|
||||||
{
|
{
|
||||||
@ -572,7 +592,7 @@ public class DiskFactory
|
|||||||
private static FormattedDisk check (FormattedDisk disk)
|
private static FormattedDisk check (FormattedDisk disk)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (disk.getDisk ()instanceof AppleDisk appleDisk)
|
if (disk.getDisk () instanceof AppleDisk appleDisk)
|
||||||
{
|
{
|
||||||
if (nuFX != null)
|
if (nuFX != null)
|
||||||
appleDisk.setNuFX (nuFX);
|
appleDisk.setNuFX (nuFX);
|
||||||
@ -597,7 +617,7 @@ public class DiskFactory
|
|||||||
if (debug)
|
if (debug)
|
||||||
System.out.println (" --> DOS");
|
System.out.println (" --> DOS");
|
||||||
DosDisk dosDisk = new DosDisk (disk);
|
DosDisk dosDisk = new DosDisk (disk);
|
||||||
// disk.setDosVersion (dosDisk.getVersion ());
|
// disk.setDosVersion (dosDisk.getVersion ());
|
||||||
|
|
||||||
return dosDisk;
|
return dosDisk;
|
||||||
}
|
}
|
||||||
@ -666,7 +686,7 @@ public class DiskFactory
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
System.out.println ("\nChecking Prodos hard disk");
|
System.out.println ("\nChecking Prodos/Pascal hard disk");
|
||||||
System.out.printf ("Total blocks : %f%n", (float) file.length () / 512);
|
System.out.printf ("Total blocks : %f%n", (float) file.length () / 512);
|
||||||
System.out.printf ("Total tracks : %f%n", (float) file.length () / 4096);
|
System.out.printf ("Total tracks : %f%n", (float) file.length () / 4096);
|
||||||
System.out.printf ("File length : %d%n", file.length ());
|
System.out.printf ("File length : %d%n", file.length ());
|
||||||
@ -690,10 +710,10 @@ public class DiskFactory
|
|||||||
System.out.println ("*** extended ***"); // System Addons.hdv
|
System.out.println ("*** extended ***"); // System Addons.hdv
|
||||||
}
|
}
|
||||||
AppleDisk disk;
|
AppleDisk disk;
|
||||||
// if (nuFX == null)
|
// if (nuFX == null)
|
||||||
disk = new AppleDisk (file, tracks, 8);
|
disk = new AppleDisk (file, tracks, 8);
|
||||||
// else
|
// else
|
||||||
// disk = new AppleDisk (file, tracks, 8, nuFX);
|
// disk = new AppleDisk (file, tracks, 8, nuFX);
|
||||||
|
|
||||||
if (ProdosDisk.isCorrectFormat (disk))
|
if (ProdosDisk.isCorrectFormat (disk))
|
||||||
{
|
{
|
||||||
@ -701,6 +721,7 @@ public class DiskFactory
|
|||||||
System.out.println (" --> PRODOS hard disk");
|
System.out.println (" --> PRODOS hard disk");
|
||||||
return new ProdosDisk (disk);
|
return new ProdosDisk (disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PascalDisk.isCorrectFormat (disk, debug))
|
if (PascalDisk.isCorrectFormat (disk, debug))
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -716,7 +737,7 @@ public class DiskFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println (" not a Prodos hard disk\n");
|
System.out.println (" not a Prodos/Pascal hard disk\n");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -841,11 +862,16 @@ public class DiskFactory
|
|||||||
|
|
||||||
if (Wizardry4BootDisk.isWizardryIVorV (disk, debug))
|
if (Wizardry4BootDisk.isWizardryIVorV (disk, debug))
|
||||||
{
|
{
|
||||||
|
if (debug)
|
||||||
|
System.out.println ("checking Wizardry IV or V");
|
||||||
|
|
||||||
String fileName = file.getAbsolutePath ().toLowerCase ();
|
String fileName = file.getAbsolutePath ().toLowerCase ();
|
||||||
int pos = file.getAbsolutePath ().indexOf ('.');
|
int pos = fileName.lastIndexOf ('.');
|
||||||
char c = fileName.charAt (pos - 1);
|
char c = fileName.charAt (pos - 1); // '1' (wiz4) or 'a' (wiz5)
|
||||||
// String suffix = fileName.substring (pos + 1);
|
int requiredDisks = c == '1' ? 7 : c == 'a' ? 10 : 0;
|
||||||
int requiredDisks = c == '1' ? 6 : c == 'a' ? 10 : 0;
|
|
||||||
|
if (debug)
|
||||||
|
System.out.printf ("Required disks: %d%n", requiredDisks);
|
||||||
|
|
||||||
if (requiredDisks > 0)
|
if (requiredDisks > 0)
|
||||||
{
|
{
|
||||||
@ -866,7 +892,7 @@ public class DiskFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println ("Not a Wizardry IV disk");
|
System.out.println ("Not a Wizardry IV or V disk");
|
||||||
|
|
||||||
PascalDisk pascalDisk = new PascalDisk (disk);
|
PascalDisk pascalDisk = new PascalDisk (disk);
|
||||||
return pascalDisk;
|
return pascalDisk;
|
||||||
@ -876,6 +902,9 @@ public class DiskFactory
|
|||||||
private static boolean collectDataDisks (String fileName, int dotPos, AppleDisk[] disks)
|
private static boolean collectDataDisks (String fileName, int dotPos, AppleDisk[] disks)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
if (debug)
|
||||||
|
System.out.println ("Collecting Wizardry disks");
|
||||||
|
|
||||||
char c = fileName.charAt (dotPos - 1);
|
char c = fileName.charAt (dotPos - 1);
|
||||||
String suffix = fileName.substring (dotPos + 1);
|
String suffix = fileName.substring (dotPos + 1);
|
||||||
|
|
||||||
@ -883,14 +912,16 @@ public class DiskFactory
|
|||||||
{
|
{
|
||||||
String old = new String (c + "." + suffix);
|
String old = new String (c + "." + suffix);
|
||||||
String rep = new String ((char) (c + i - 1) + "." + suffix);
|
String rep = new String ((char) (c + i - 1) + "." + suffix);
|
||||||
|
|
||||||
File f = new File (fileName.replace (old, rep));
|
File f = new File (fileName.replace (old, rep));
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
System.out.println (f);
|
||||||
|
|
||||||
if (!f.exists () || !f.isFile ())
|
if (!f.exists () || !f.isFile ())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AppleDisk dataDisk = new AppleDisk (f, 35, 8);
|
disks[i] = new AppleDisk (f, 35, 8);
|
||||||
dataDisk.setInterleave (1);
|
disks[i].setInterleave (1);
|
||||||
disks[i] = dataDisk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -931,4 +962,22 @@ public class DiskFactory
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private static byte[] getPrefix (File file)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
try (BufferedInputStream bis = new BufferedInputStream (new FileInputStream (file)))
|
||||||
|
{
|
||||||
|
bis.read (buffer);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace ();
|
||||||
|
System.exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
}
|
}
|
@ -51,6 +51,9 @@ public class Prefix2mg
|
|||||||
if (format == 0 && flagsVolume == 0)
|
if (format == 0 && flagsVolume == 0)
|
||||||
flagsVolume = 254;
|
flagsVolume = 254;
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
length = 512 * blocks;
|
||||||
|
|
||||||
// see /Asimov disks/images/gs/os/prodos16/ProDOS 16v1_3.2mg
|
// see /Asimov disks/images/gs/os/prodos16/ProDOS 16v1_3.2mg
|
||||||
// System.out.println (this);
|
// System.out.println (this);
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@ public class SectorListConverter
|
|||||||
sectors = new ArrayList<> ();
|
sectors = new ArrayList<> ();
|
||||||
sectorText = text;
|
sectorText = text;
|
||||||
|
|
||||||
String[] blocks = text.split (";");
|
for (String s : text.split (";"))
|
||||||
for (String s : blocks)
|
|
||||||
{
|
{
|
||||||
int pos = s.indexOf ('-');
|
int pos = s.indexOf ('-');
|
||||||
if (pos > 0)
|
if (pos > 0)
|
||||||
|
@ -89,8 +89,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
|||||||
lastModified = Utility.getDateTime (entryBuffer, 0x1B);
|
lastModified = Utility.getDateTime (entryBuffer, 0x1B);
|
||||||
|
|
||||||
// CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6
|
// CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6
|
||||||
String base = String.format ("%s%s %03d ", locked ? "*" : " ", getFileType (),
|
String base =
|
||||||
reportedSize & 0xFF);
|
String.format ("%s%s %03d ", locked ? "*" : " ", getFileType (), reportedSize & 0xFF);
|
||||||
catalogName = getName (base, entryBuffer);
|
catalogName = getName (base, entryBuffer);
|
||||||
displayName = getDisplayName (entryBuffer);
|
displayName = getDisplayName (entryBuffer);
|
||||||
}
|
}
|
||||||
@ -235,18 +235,28 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
|||||||
|
|
||||||
case IntegerBasic:
|
case IntegerBasic:
|
||||||
reportedLength = Utility.getShort (buffer, 0);
|
reportedLength = Utility.getShort (buffer, 0);
|
||||||
exactBuffer = new byte[reportedLength];
|
if (reportedLength > 0)
|
||||||
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
|
{
|
||||||
appleFile = new IntegerBasicProgram (name, exactBuffer);
|
exactBuffer = new byte[reportedLength];
|
||||||
|
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
|
||||||
|
appleFile = new IntegerBasicProgram (name, exactBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appleFile = new DefaultAppleFile (name, buffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ApplesoftBasic:
|
case ApplesoftBasic:
|
||||||
reportedLength = Utility.getShort (buffer, 0);
|
reportedLength = Utility.getShort (buffer, 0);
|
||||||
exactBuffer = new byte[reportedLength];
|
if (reportedLength > 0)
|
||||||
if (reportedLength > buffer.length)
|
{
|
||||||
reportedLength = buffer.length - 2;
|
exactBuffer = new byte[reportedLength];
|
||||||
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
|
if (reportedLength > buffer.length)
|
||||||
appleFile = new ApplesoftBasicProgram (name, exactBuffer);
|
reportedLength = buffer.length - 2;
|
||||||
|
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
|
||||||
|
appleFile = new ApplesoftBasicProgram (name, exactBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appleFile = new DefaultAppleFile (name, buffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Binary: // binary file
|
case Binary: // binary file
|
||||||
@ -256,8 +266,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
|||||||
reportedLength = Utility.getShort (buffer, 2);
|
reportedLength = Utility.getShort (buffer, 2);
|
||||||
if (reportedLength == 0)
|
if (reportedLength == 0)
|
||||||
{
|
{
|
||||||
System.out.println (name.trim () + " reported length : 0 - reverting to "
|
System.out.println (
|
||||||
+ (buffer.length - 4));
|
name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
|
||||||
reportedLength = buffer.length - 4;
|
reportedLength = buffer.length - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,9 +278,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
|||||||
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
|
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
|
||||||
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
|
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
|
||||||
|
|
||||||
if ((name.endsWith (".FONT") || name.endsWith (" FONT")
|
if ((name.endsWith (".FONT") || name.endsWith (" FONT") || name.endsWith (".SET")
|
||||||
|| name.endsWith (".SET") || name.startsWith ("ASCII."))
|
|| name.startsWith ("ASCII.")) && FontFile.isFont (exactBuffer))
|
||||||
&& FontFile.isFont (exactBuffer))
|
|
||||||
appleFile = new FontFile (name, exactBuffer, loadAddress);
|
appleFile = new FontFile (name, exactBuffer, loadAddress);
|
||||||
else if (name.endsWith (".MW"))
|
else if (name.endsWith (".MW"))
|
||||||
appleFile = new MagicWindowText (name, exactBuffer);
|
appleFile = new MagicWindowText (name, exactBuffer);
|
||||||
@ -305,8 +314,7 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
|||||||
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
|
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
|
||||||
}
|
}
|
||||||
else if (reportedLength == 0x240 //
|
else if (reportedLength == 0x240 //
|
||||||
&& (loadAddress == 0x5800 || loadAddress == 0x6000
|
&& (loadAddress == 0x5800 || loadAddress == 0x6000 || loadAddress == 0x7800))
|
||||||
|| loadAddress == 0x7800))
|
|
||||||
appleFile = new PrintShopGraphic (name, exactBuffer);
|
appleFile = new PrintShopGraphic (name, exactBuffer);
|
||||||
else if (isRunCommand (exactBuffer))
|
else if (isRunCommand (exactBuffer))
|
||||||
{
|
{
|
||||||
@ -319,8 +327,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
|||||||
{
|
{
|
||||||
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
|
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
|
||||||
if ((exactBuffer.length + 4) < buffer.length)
|
if ((exactBuffer.length + 4) < buffer.length)
|
||||||
((AssemblerProgram) appleFile).setExtraBuffer (buffer,
|
((AssemblerProgram) appleFile).setExtraBuffer (buffer, exactBuffer.length + 4,
|
||||||
exactBuffer.length + 4, buffer.length - (exactBuffer.length + 4));
|
buffer.length - (exactBuffer.length + 4));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -362,8 +370,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
|
|||||||
int reportedLength = Utility.getShort (buffer, 2);
|
int reportedLength = Utility.getShort (buffer, 2);
|
||||||
if (reportedLength == 0)
|
if (reportedLength == 0)
|
||||||
{
|
{
|
||||||
System.out.println (
|
System.out
|
||||||
name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
|
.println (name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
|
||||||
reportedLength = buffer.length - 4;
|
reportedLength = buffer.length - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +326,8 @@ public class DosDisk extends AbstractFormattedDisk
|
|||||||
return "4.2";
|
return "4.2";
|
||||||
case 0x43:
|
case 0x43:
|
||||||
return "4.3";
|
return "4.3";
|
||||||
|
case 0x45:
|
||||||
|
return "4.5";
|
||||||
default:
|
default:
|
||||||
return "??";
|
return "??";
|
||||||
}
|
}
|
||||||
@ -376,7 +378,7 @@ public class DosDisk extends AbstractFormattedDisk
|
|||||||
int version = buffer[3] & 0xFF;
|
int version = buffer[3] & 0xFF;
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.printf ("Version: %02X%n", buffer[3]);
|
System.out.printf ("Version: %02X%n", buffer[3]);
|
||||||
if (version == 0 || (version > 0x43 && version != 0xFF))
|
if (version == 0 || (version > 0x45 && version != 0xFF))
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.printf ("Bad version : %02X%n", version);
|
System.out.printf ("Bad version : %02X%n", version);
|
||||||
|
@ -120,7 +120,7 @@ public class DisksWindow extends JFrame
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollPane.setPreferredSize (new Dimension (1200, 700));
|
scrollPane.setPreferredSize (new Dimension (1200, 693));
|
||||||
setDefaultCloseOperation (HIDE_ON_CLOSE);
|
setDefaultCloseOperation (HIDE_ON_CLOSE);
|
||||||
|
|
||||||
deleteWindow = new DeleteWindow (rootFolderData);
|
deleteWindow = new DeleteWindow (rootFolderData);
|
||||||
|
@ -8,6 +8,8 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -20,11 +22,10 @@ import javax.swing.JFrame;
|
|||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener;
|
import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener;
|
||||||
import com.bytezone.diskbrowser.gui.RootDirectoryChangeListener;
|
|
||||||
import com.bytezone.diskbrowser.utilities.Utility;
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class RootFolderData implements RootDirectoryChangeListener
|
public class RootFolderData implements PropertyChangeListener
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final String header =
|
private static final String header =
|
||||||
@ -177,38 +178,35 @@ public class RootFolderData implements RootDirectoryChangeListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void incrementType (File file, String filename)
|
public void incrementType (File file, String fileName)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
int pos = Utility.getSuffixNo (filename);
|
int pos = Utility.getSuffixNo (fileName);
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
{
|
{
|
||||||
int cmp = 0;
|
int cmp = fileName.endsWith (".zip") ? 2 : fileName.endsWith (".gz") ? 1 : 0;
|
||||||
if (filename.endsWith (".gz"))
|
|
||||||
cmp = 1;
|
|
||||||
else if (filename.endsWith (".zip"))
|
|
||||||
cmp = 2;
|
|
||||||
typeTotals[cmp][pos]++;
|
typeTotals[cmp][pos]++;
|
||||||
typeTotals[3][pos]++;
|
typeTotals[3][pos]++;
|
||||||
++totalDisks;
|
++totalDisks;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
System.out.println ("no suffix: " + filename);
|
System.out.println ("no suffix: " + fileName);
|
||||||
|
|
||||||
checkDuplicates (file, filename);
|
checkDuplicates (file, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private void checkDuplicates (File file, String filename)
|
private void checkDuplicates (File file, String fileName)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
String rootName = file.getAbsolutePath ().substring (rootFolderNameLength);
|
String rootName = file.getAbsolutePath ().substring (rootFolderNameLength);
|
||||||
DiskDetails diskDetails = new DiskDetails (file, rootName, filename, doChecksums);
|
DiskDetails diskDetails = new DiskDetails (file, rootName, fileName, doChecksums);
|
||||||
|
|
||||||
if (fileNameMap.containsKey (filename))
|
if (fileNameMap.containsKey (fileName))
|
||||||
fileNameMap.get (filename).addDuplicateName (diskDetails);
|
fileNameMap.get (fileName).addDuplicateName (diskDetails);
|
||||||
else
|
else
|
||||||
fileNameMap.put (filename, diskDetails);
|
fileNameMap.put (fileName, diskDetails);
|
||||||
|
|
||||||
if (doChecksums)
|
if (doChecksums)
|
||||||
{
|
{
|
||||||
@ -277,8 +275,7 @@ public class RootFolderData implements RootDirectoryChangeListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
private void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
|
||||||
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
rootFolder = newRootFolder;
|
rootFolder = newRootFolder;
|
||||||
@ -286,6 +283,15 @@ public class RootFolderData implements RootDirectoryChangeListener
|
|||||||
disksWindow = null; // force a recount
|
disksWindow = null; // force a recount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void propertyChange (PropertyChangeEvent evt)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (evt.getPropertyName ().equals ("RootDirectory"))
|
||||||
|
rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ());
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public String toString ()
|
public String toString ()
|
||||||
@ -326,16 +332,16 @@ public class RootFolderData implements RootDirectoryChangeListener
|
|||||||
int grandTotal[] = new int[4];
|
int grandTotal[] = new int[4];
|
||||||
|
|
||||||
for (int i = 0; i < typeTotals[0].length; i++)
|
for (int i = 0; i < typeTotals[0].length; i++)
|
||||||
{
|
if (typeTotals[3][i] > 0)
|
||||||
line = String.format ("%14.14s %,7d %,7d %,7d %,7d",
|
{
|
||||||
Utility.getSuffix (i) + " ...........", typeTotals[0][i], typeTotals[1][i],
|
line = String.format ("%14.14s %,7d %,7d %,7d %,7d",
|
||||||
typeTotals[2][i], typeTotals[3][i]);
|
Utility.getSuffix (i) + " ...........", typeTotals[0][i], typeTotals[1][i],
|
||||||
g.drawString (line, x, y);
|
typeTotals[2][i], typeTotals[3][i]);
|
||||||
for (int j = 0; j < typeTotals.length; j++)
|
g.drawString (line, x, y);
|
||||||
grandTotal[j] += typeTotals[j][i];
|
for (int j = 0; j < typeTotals.length; j++)
|
||||||
|
grandTotal[j] += typeTotals[j][i];
|
||||||
y += lineHeight;
|
y += lineHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = String.format ("Total %,7d %,7d %,7d %,7d%n%n", grandTotal[0],
|
line = String.format ("Total %,7d %,7d %,7d %,7d%n%n", grandTotal[0],
|
||||||
grandTotal[1], grandTotal[2], grandTotal[3]);
|
grandTotal[1], grandTotal[2], grandTotal[3]);
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
package com.bytezone.diskbrowser.gui;
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.utilities.DefaultAction;
|
import com.bytezone.diskbrowser.utilities.DefaultAction;
|
||||||
|
|
||||||
@ -8,13 +15,44 @@ import com.bytezone.diskbrowser.utilities.DefaultAction;
|
|||||||
public abstract class AbstractSaveAction extends DefaultAction
|
public abstract class AbstractSaveAction extends DefaultAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
JFileChooser fileChooser;
|
protected JFileChooser fileChooser = new JFileChooser ();
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public AbstractSaveAction (String text, String tip)
|
public AbstractSaveAction (String menuText, String tip, String dialogTitle)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super (text, tip);
|
super (menuText, tip);
|
||||||
|
|
||||||
|
fileChooser.setDialogTitle (dialogTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
void setSelectedFile (File file)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
fileChooser.setSelectedFile (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
void saveBuffer (byte[] buffer)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
File file = fileChooser.getSelectedFile ();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Files.write (file.toPath (), buffer, StandardOpenOption.CREATE_NEW);
|
||||||
|
JOptionPane.showMessageDialog (null, String.format ("File %s saved", file.getName ()));
|
||||||
|
}
|
||||||
|
catch (FileAlreadyExistsException e)
|
||||||
|
{
|
||||||
|
JOptionPane.showMessageDialog (null, "File " + file.getName () + " already exists", "Failed",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace ();
|
||||||
|
JOptionPane.showMessageDialog (null, "File failed to save - " + e.getMessage (), "Failed",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
62
src/com/bytezone/diskbrowser/gui/AnimationWorker.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.applefile.SHRPictureFile2;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
public class AnimationWorker extends SwingWorker<Void, Integer>
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
volatile boolean running;
|
||||||
|
SHRPictureFile2 image;
|
||||||
|
OutputPanel owner;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public AnimationWorker (OutputPanel owner, SHRPictureFile2 image)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
assert image.isAnimation ();
|
||||||
|
this.image = image;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void cancel ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground () throws Exception
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
running = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
Thread.sleep (image.getDelay ());
|
||||||
|
publish (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace ();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
protected void process (List<Integer> chunks)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
image.nextFrame ();
|
||||||
|
owner.update ();
|
||||||
|
}
|
||||||
|
}
|
@ -158,9 +158,9 @@ class AppleDiskTab extends AbstractTab
|
|||||||
|
|
||||||
// check for multi-volume disk (only search the current branch)
|
// check for multi-volume disk (only search the current branch)
|
||||||
FormattedDisk fd = ((AppleFileSource) rootNode.getUserObject ()).getFormattedDisk ();
|
FormattedDisk fd = ((AppleFileSource) rootNode.getUserObject ()).getFormattedDisk ();
|
||||||
if (fd instanceof HybridDisk)
|
if (fd instanceof HybridDisk hd)
|
||||||
{
|
{
|
||||||
int volume = ((HybridDisk) fd).getCurrentDiskNo ();
|
int volume = hd.getCurrentDiskNo ();
|
||||||
rootNode = (DefaultMutableTreeNode) rootNode.getChildAt (volume);
|
rootNode = (DefaultMutableTreeNode) rootNode.getChildAt (volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,8 +169,8 @@ class AppleDiskTab extends AbstractTab
|
|||||||
{
|
{
|
||||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) children.nextElement ();
|
DefaultMutableTreeNode node = (DefaultMutableTreeNode) children.nextElement ();
|
||||||
Object userObject = node.getUserObject ();
|
Object userObject = node.getUserObject ();
|
||||||
if (userObject instanceof AppleFileSource
|
if (userObject instanceof AppleFileSource afs
|
||||||
&& nodeName.equals (((AppleFileSource) userObject).getUniqueName ()))
|
&& nodeName.equals (afs.getUniqueName ()))
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -10,6 +10,8 @@ import java.awt.Dimension;
|
|||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
@ -36,9 +38,8 @@ import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
|
|||||||
import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode;
|
import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class CatalogPanel extends JTabbedPane
|
class CatalogPanel extends JTabbedPane implements RedoListener, SectorSelectionListener,
|
||||||
implements RedoListener, SectorSelectionListener, QuitListener, FontChangeListener,
|
QuitListener, FontChangeListener, DiskTableSelectionListener, PropertyChangeListener
|
||||||
RootDirectoryChangeListener, DiskTableSelectionListener
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final String prefsLastDiskUsed = "Last disk used";
|
private static final String prefsLastDiskUsed = "Last disk used";
|
||||||
@ -66,8 +67,7 @@ class CatalogPanel extends JTabbedPane
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
private void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
|
||||||
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
rootFolder = newRootFolder;
|
rootFolder = newRootFolder;
|
||||||
@ -82,6 +82,18 @@ class CatalogPanel extends JTabbedPane
|
|||||||
setSelectedIndex (0);
|
setSelectedIndex (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void propertyChange (PropertyChangeEvent evt)
|
||||||
|
// -------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (evt.getPropertyName ().equals ("RootDirectory"))
|
||||||
|
rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ());
|
||||||
|
// else
|
||||||
|
// closeCurrentTab ();
|
||||||
|
// System.out.println (evt.getPropertyName ());
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private void insertFileSystemTab (DiskSelectedEvent diskEvent)
|
private void insertFileSystemTab (DiskSelectedEvent diskEvent)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -146,11 +158,10 @@ class CatalogPanel extends JTabbedPane
|
|||||||
tab.refresh ();
|
tab.refresh ();
|
||||||
|
|
||||||
// Any newly created disk needs to appear in the FileSystemTab's tree
|
// Any newly created disk needs to appear in the FileSystemTab's tree
|
||||||
if (tab instanceof AppleDiskTab)
|
if (tab instanceof AppleDiskTab appleDiskTab)
|
||||||
fileTab.replaceDisk (((AppleDiskTab) tab).disk);
|
fileTab.replaceDisk (appleDiskTab.disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from CloseTabAction
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void closeCurrentTab ()
|
public void closeCurrentTab ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -174,10 +185,7 @@ class CatalogPanel extends JTabbedPane
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
Tab tab = (Tab) getSelectedComponent ();
|
Tab tab = (Tab) getSelectedComponent ();
|
||||||
if (diskTabs.size () > 1 && tab instanceof AppleDiskTab)
|
closeTabAction.setEnabled (diskTabs.size () > 1 && tab instanceof AppleDiskTab);
|
||||||
closeTabAction.setEnabled (true);
|
|
||||||
else
|
|
||||||
closeTabAction.setEnabled (false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -213,8 +221,8 @@ class CatalogPanel extends JTabbedPane
|
|||||||
|
|
||||||
FormattedDisk fd = ((AppleDiskTab) selectedTab).disk;
|
FormattedDisk fd = ((AppleDiskTab) selectedTab).disk;
|
||||||
prefs.put (prefsLastDiskUsed, fd.getAbsolutePath ());
|
prefs.put (prefsLastDiskUsed, fd.getAbsolutePath ());
|
||||||
if (fd instanceof HybridDisk)
|
if (fd instanceof HybridDisk hybridDisk)
|
||||||
prefs.putInt (prefsLastDosUsed, ((HybridDisk) fd).getCurrentDiskNo ());
|
prefs.putInt (prefsLastDosUsed, hybridDisk.getCurrentDiskNo ());
|
||||||
else
|
else
|
||||||
prefs.putInt (prefsLastDosUsed, -1);
|
prefs.putInt (prefsLastDosUsed, -1);
|
||||||
|
|
||||||
@ -223,16 +231,16 @@ class CatalogPanel extends JTabbedPane
|
|||||||
{
|
{
|
||||||
EventObject event = redoEvent.value;
|
EventObject event = redoEvent.value;
|
||||||
|
|
||||||
if (event instanceof FileSelectedEvent)
|
if (event instanceof FileSelectedEvent fileSelectedEvent)
|
||||||
{
|
{
|
||||||
AppleFileSource afs = ((FileSelectedEvent) event).appleFileSource;
|
AppleFileSource afs = fileSelectedEvent.appleFileSource;
|
||||||
prefs.put (prefsLastFileUsed, afs == null ? "" : afs.getUniqueName ());
|
prefs.put (prefsLastFileUsed, afs == null ? "" : afs.getUniqueName ());
|
||||||
prefs.put (prefsLastSectorsUsed, "");
|
prefs.put (prefsLastSectorsUsed, "");
|
||||||
}
|
}
|
||||||
else if (event instanceof SectorSelectedEvent)
|
else if (event instanceof SectorSelectedEvent sectorSelectedEvent)
|
||||||
{
|
{
|
||||||
prefs.put (prefsLastFileUsed, "");
|
prefs.put (prefsLastFileUsed, "");
|
||||||
prefs.put (prefsLastSectorsUsed, ((SectorSelectedEvent) event).toText ());
|
prefs.put (prefsLastSectorsUsed, sectorSelectedEvent.toText ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,8 +273,8 @@ class CatalogPanel extends JTabbedPane
|
|||||||
if (diskEvent != null)
|
if (diskEvent != null)
|
||||||
{
|
{
|
||||||
fd1 = diskEvent.getFormattedDisk ();
|
fd1 = diskEvent.getFormattedDisk ();
|
||||||
if (lastDosUsed >= 0 && fd1 instanceof HybridDisk)
|
if (lastDosUsed >= 0 && fd1 instanceof HybridDisk hybridDisk)
|
||||||
((HybridDisk) fd1).setCurrentDiskNo (lastDosUsed);
|
hybridDisk.setCurrentDiskNo (lastDosUsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -321,6 +329,14 @@ class CatalogPanel extends JTabbedPane
|
|||||||
selector.addDiskSelectionListener (listener);
|
selector.addDiskSelectionListener (listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void addDiskSelectionListener (DiskSelectionListener... listeners)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
for (DiskSelectionListener diskSelectionListener : listeners)
|
||||||
|
selector.addDiskSelectionListener (diskSelectionListener);
|
||||||
|
}
|
||||||
|
|
||||||
// Pass through to DiskSelector
|
// Pass through to DiskSelector
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void addFileSelectionListener (FileSelectionListener listener)
|
public void addFileSelectionListener (FileSelectionListener listener)
|
||||||
@ -329,6 +345,14 @@ class CatalogPanel extends JTabbedPane
|
|||||||
selector.addFileSelectionListener (listener);
|
selector.addFileSelectionListener (listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void addFileSelectionListener (FileSelectionListener... listeners)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
for (FileSelectionListener fileSelectionListener : listeners)
|
||||||
|
selector.addFileSelectionListener (fileSelectionListener);
|
||||||
|
}
|
||||||
|
|
||||||
// Pass through to DiskSelector
|
// Pass through to DiskSelector
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void addFileNodeSelectionListener (FileNodeSelectionListener listener)
|
public void addFileNodeSelectionListener (FileNodeSelectionListener listener)
|
||||||
@ -337,6 +361,14 @@ class CatalogPanel extends JTabbedPane
|
|||||||
selector.addFileNodeSelectionListener (listener);
|
selector.addFileNodeSelectionListener (listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void addFileNodeSelectionListener (FileNodeSelectionListener... listeners)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
for (FileNodeSelectionListener fileNodeSelectionListener : listeners)
|
||||||
|
selector.addFileNodeSelectionListener (fileNodeSelectionListener);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private class TabChangeListener implements ChangeListener
|
private class TabChangeListener implements ChangeListener
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -367,13 +399,13 @@ class CatalogPanel extends JTabbedPane
|
|||||||
{
|
{
|
||||||
case "DiskEvent":
|
case "DiskEvent":
|
||||||
case "FileNodeEvent":
|
case "FileNodeEvent":
|
||||||
if (tab instanceof FileSystemTab)
|
if (tab instanceof FileSystemTab fileSystemTab)
|
||||||
((FileSystemTab) tab).redoEvent (event);
|
fileSystemTab.redoEvent (event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "FileEvent":
|
case "FileEvent":
|
||||||
if (tab instanceof AppleDiskTab)
|
if (tab instanceof AppleDiskTab appleDiskTab)
|
||||||
((AppleDiskTab) tab).redoEvent (event);
|
appleDiskTab.redoEvent (event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "SectorEvent":
|
case "SectorEvent":
|
||||||
@ -394,8 +426,8 @@ class CatalogPanel extends JTabbedPane
|
|||||||
{
|
{
|
||||||
// user has clicked in the DiskLayoutPanel, so turn off any current file selection
|
// user has clicked in the DiskLayoutPanel, so turn off any current file selection
|
||||||
Tab tab = (Tab) getSelectedComponent ();
|
Tab tab = (Tab) getSelectedComponent ();
|
||||||
if (tab instanceof AppleDiskTab)
|
if (tab instanceof AppleDiskTab appleDiskTab)
|
||||||
((AppleDiskTab) tab).tree.setSelectionPath (null);
|
appleDiskTab.tree.setSelectionPath (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -430,7 +462,7 @@ class CatalogPanel extends JTabbedPane
|
|||||||
FileNode node = (FileNode) selectedNode.getUserObject ();
|
FileNode node = (FileNode) selectedNode.getUserObject ();
|
||||||
if (node.file.isDirectory ())
|
if (node.file.isDirectory ())
|
||||||
{
|
{
|
||||||
// lister.catalogLister.setNode (selectedNode);
|
// lister.catalogLister.setNode (selectedNode);
|
||||||
}
|
}
|
||||||
else if (e.getClickCount () == 2)
|
else if (e.getClickCount () == 2)
|
||||||
addDiskPanel (node.getFormattedDisk (), true);
|
addDiskPanel (node.getFormattedDisk (), true);
|
||||||
|
@ -19,6 +19,7 @@ public class CloseTabAction extends AbstractAction
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Close Tab");
|
super ("Close Tab");
|
||||||
|
|
||||||
putValue (Action.SHORT_DESCRIPTION, "Close the current disk tab");
|
putValue (Action.SHORT_DESCRIPTION, "Close the current disk tab");
|
||||||
// putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("ctrl W"));
|
// putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("ctrl W"));
|
||||||
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
|
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
|
||||||
|
@ -12,17 +12,15 @@ import javax.swing.KeyStroke;
|
|||||||
public class ColourQuirksAction extends AbstractAction
|
public class ColourQuirksAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final DataPanel owner;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public ColourQuirksAction (DataPanel owner)
|
public ColourQuirksAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Smear HGR");
|
super ("Smear HGR");
|
||||||
|
|
||||||
putValue (Action.SHORT_DESCRIPTION, "Display pixels like a TV screen");
|
putValue (Action.SHORT_DESCRIPTION, "Display pixels like a TV screen");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt Q"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt Q"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_Q);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_Q);
|
||||||
this.owner = owner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -30,6 +28,7 @@ public class ColourQuirksAction extends AbstractAction
|
|||||||
public void actionPerformed (ActionEvent e)
|
public void actionPerformed (ActionEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
owner.setColourQuirks (((JMenuItem) e.getSource ()).isSelected ());
|
firePropertyChange (e.getActionCommand (), null,
|
||||||
|
((JMenuItem) e.getSource ()).isSelected ());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,16 +11,14 @@ import javax.swing.KeyStroke;
|
|||||||
public class DebuggingAction extends AbstractAction
|
public class DebuggingAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final DataPanel owner;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public DebuggingAction (DataPanel owner)
|
public DebuggingAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Debugging");
|
super ("Debugging");
|
||||||
|
|
||||||
putValue (Action.SHORT_DESCRIPTION, "Show debugging information");
|
putValue (Action.SHORT_DESCRIPTION, "Show debugging information");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("meta D"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("meta D"));
|
||||||
this.owner = owner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -28,6 +26,7 @@ public class DebuggingAction extends AbstractAction
|
|||||||
public void actionPerformed (ActionEvent e)
|
public void actionPerformed (ActionEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
owner.setDebug (((JMenuItem) e.getSource ()).isSelected ());
|
firePropertyChange (e.getActionCommand (), null,
|
||||||
|
((JMenuItem) e.getSource ()).isSelected ());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,8 @@ import java.awt.Desktop;
|
|||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
@ -22,7 +24,8 @@ import javax.swing.UIManager;
|
|||||||
import com.bytezone.diskbrowser.duplicates.RootFolderData;
|
import com.bytezone.diskbrowser.duplicates.RootFolderData;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitListener
|
public class DiskBrowser extends JFrame
|
||||||
|
implements DiskSelectionListener, QuitListener, PropertyChangeListener
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static String[] args;
|
private static String[] args;
|
||||||
@ -35,13 +38,21 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
|
|
||||||
private final RootFolderData rootFolderData = new RootFolderData ();
|
private final RootFolderData rootFolderData = new RootFolderData ();
|
||||||
|
|
||||||
|
private final List<QuitListener> quitListeners = new ArrayList<> ();
|
||||||
|
|
||||||
|
private final JPanel catalogBorderPanel;
|
||||||
|
private final JPanel layoutBorderPanel;
|
||||||
|
|
||||||
|
private final HideCatalogAction hideCatalogAction = new HideCatalogAction ();
|
||||||
|
private final HideLayoutAction hideLayoutAction = new HideLayoutAction ();
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public DiskBrowser ()
|
public DiskBrowser ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super (windowTitle);
|
super (windowTitle);
|
||||||
|
|
||||||
UIManager.put ("TabbedPane.foreground", Color.BLACK); // java bug fix
|
// UIManager.put ("TabbedPane.foreground", Color.BLACK); // java bug fix
|
||||||
|
|
||||||
if (args.length > 0 && "-reset".equals (args[0]))
|
if (args.length > 0 && "-reset".equals (args[0]))
|
||||||
new WindowState (prefs).clear ();
|
new WindowState (prefs).clear ();
|
||||||
@ -59,65 +70,56 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
|
|
||||||
// create and add the left-hand catalog panel
|
// create and add the left-hand catalog panel
|
||||||
CatalogPanel catalogPanel = new CatalogPanel (redoHandler);
|
CatalogPanel catalogPanel = new CatalogPanel (redoHandler);
|
||||||
JPanel catalogBorderPanel = addPanel (catalogPanel, "Catalog", BorderLayout.WEST);
|
catalogBorderPanel = addPanel (catalogPanel, "Catalog", BorderLayout.WEST);
|
||||||
|
|
||||||
// create and add the centre output panel
|
// create and add the centre output panel
|
||||||
DataPanel dataPanel = new DataPanel (menuHandler);
|
OutputPanel dataPanel = new OutputPanel (menuHandler);
|
||||||
addPanel (dataPanel, "Output", BorderLayout.CENTER);
|
addPanel (dataPanel, "Output", BorderLayout.CENTER);
|
||||||
|
|
||||||
// create and add the right-hand disk layout panel
|
// create and add the right-hand disk layout panel
|
||||||
DiskLayoutPanel diskLayoutPanel = new DiskLayoutPanel ();
|
DiskLayoutPanel diskLayoutPanel = new DiskLayoutPanel ();
|
||||||
JPanel layoutBorderPanel =
|
layoutBorderPanel = addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
|
||||||
addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
|
|
||||||
|
|
||||||
// create actions
|
// create actions
|
||||||
DuplicateAction duplicateAction = new DuplicateAction (rootFolderData);
|
DuplicateAction duplicateAction = new DuplicateAction (rootFolderData);
|
||||||
RootDirectoryAction rootDirectoryAction = new RootDirectoryAction ();
|
RootDirectoryAction rootDirectoryAction = new RootDirectoryAction ();
|
||||||
|
|
||||||
RefreshTreeAction refreshTreeAction = new RefreshTreeAction (catalogPanel);
|
RefreshTreeAction refreshTreeAction = new RefreshTreeAction (catalogPanel);
|
||||||
// PreferencesAction preferencesAction = new PreferencesAction (this, prefs);
|
// PreferencesAction preferencesAction = new PreferencesAction (this, prefs);
|
||||||
AbstractAction print = new PrintAction (dataPanel);
|
AbstractAction print = new PrintAction (dataPanel);
|
||||||
// AboutAction aboutAction = new AboutAction ();
|
// AboutAction aboutAction = new AboutAction ();
|
||||||
HideCatalogAction hideCatalogAction =
|
// HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
|
||||||
new HideCatalogAction (this, catalogBorderPanel);
|
ShowFreeSectorsAction showFreeAction = new ShowFreeSectorsAction ();
|
||||||
HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
|
|
||||||
ShowFreeSectorsAction showFreeAction =
|
|
||||||
new ShowFreeSectorsAction (menuHandler, diskLayoutPanel);
|
|
||||||
CloseTabAction closeTabAction = new CloseTabAction (catalogPanel);
|
CloseTabAction closeTabAction = new CloseTabAction (catalogPanel);
|
||||||
|
// closeTabAction.addPropertyChangeListener (catalogPanel);
|
||||||
|
|
||||||
|
hideCatalogAction.addPropertyChangeListener (this);
|
||||||
|
hideLayoutAction.addPropertyChangeListener (this);
|
||||||
|
|
||||||
// add action buttons to toolbar
|
// add action buttons to toolbar
|
||||||
toolBar.add (rootDirectoryAction);
|
toolBar.add (rootDirectoryAction);
|
||||||
toolBar.add (refreshTreeAction);
|
toolBar.add (refreshTreeAction);
|
||||||
// toolBar.add (preferencesAction);
|
// toolBar.add (preferencesAction);
|
||||||
toolBar.add (duplicateAction);
|
toolBar.add (duplicateAction);
|
||||||
toolBar.add (print);
|
toolBar.add (print);
|
||||||
// toolBar.add (aboutAction);
|
// toolBar.add (aboutAction);
|
||||||
|
|
||||||
// set the listeners
|
// set the listeners
|
||||||
rootDirectoryAction.addListener (rootFolderData);
|
rootDirectoryAction.addPropertyChangeListener (rootFolderData);
|
||||||
rootDirectoryAction.addListener (catalogPanel);
|
rootDirectoryAction.addPropertyChangeListener (catalogPanel);
|
||||||
rootDirectoryAction.addListener (duplicateAction);
|
rootDirectoryAction.addPropertyChangeListener (duplicateAction);
|
||||||
|
|
||||||
catalogPanel.addDiskSelectionListener (this);
|
catalogPanel.addDiskSelectionListener (this, dataPanel, diskLayoutPanel, redoHandler,
|
||||||
catalogPanel.addDiskSelectionListener (dataPanel);
|
menuHandler, menuHandler.saveDiskAction);
|
||||||
catalogPanel.addDiskSelectionListener (diskLayoutPanel);
|
|
||||||
catalogPanel.addDiskSelectionListener (redoHandler);
|
|
||||||
catalogPanel.addDiskSelectionListener (menuHandler);
|
|
||||||
catalogPanel.addDiskSelectionListener (menuHandler.saveDiskAction);
|
|
||||||
|
|
||||||
catalogPanel.addFileSelectionListener (dataPanel);
|
catalogPanel.addFileSelectionListener (dataPanel, diskLayoutPanel, redoHandler, menuHandler,
|
||||||
catalogPanel.addFileSelectionListener (diskLayoutPanel);
|
menuHandler.saveFileAction);
|
||||||
catalogPanel.addFileSelectionListener (redoHandler);
|
|
||||||
catalogPanel.addFileSelectionListener (menuHandler);
|
|
||||||
catalogPanel.addFileSelectionListener (menuHandler.saveFileAction);
|
|
||||||
|
|
||||||
catalogPanel.addFileNodeSelectionListener (dataPanel);
|
catalogPanel.addFileNodeSelectionListener (dataPanel, redoHandler);
|
||||||
catalogPanel.addFileNodeSelectionListener (redoHandler);
|
|
||||||
|
|
||||||
diskLayoutPanel.addSectorSelectionListener (dataPanel);
|
diskLayoutPanel.addSectorSelectionListener (dataPanel, redoHandler, catalogPanel,
|
||||||
diskLayoutPanel.addSectorSelectionListener (redoHandler);
|
menuHandler.saveSectorsAction);
|
||||||
diskLayoutPanel.addSectorSelectionListener (catalogPanel);
|
|
||||||
diskLayoutPanel.addSectorSelectionListener (menuHandler.saveSectorsAction);
|
|
||||||
|
|
||||||
duplicateAction.addTableSelectionListener (catalogPanel);
|
duplicateAction.addTableSelectionListener (catalogPanel);
|
||||||
|
|
||||||
@ -130,12 +132,10 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
|
|
||||||
menuHandler.fontAction.addFontChangeListener (dataPanel);
|
menuHandler.fontAction.addFontChangeListener (dataPanel);
|
||||||
menuHandler.fontAction.addFontChangeListener (catalogPanel);
|
menuHandler.fontAction.addFontChangeListener (catalogPanel);
|
||||||
// menuHandler.fontAction.addFontChangeListener (diskLayoutPanel);
|
// menuHandler.fontAction.addFontChangeListener (diskLayoutPanel);
|
||||||
|
|
||||||
// set the MenuItem Actions
|
// set the MenuItem Actions
|
||||||
menuHandler.printItem.setAction (print);
|
menuHandler.printItem.setAction (print);
|
||||||
// menuHandler.addHelpMenuAction (preferencesAction, "prefs");
|
|
||||||
// menuHandler.addHelpMenuAction (aboutAction, "about");
|
|
||||||
menuHandler.refreshTreeItem.setAction (refreshTreeAction);
|
menuHandler.refreshTreeItem.setAction (refreshTreeAction);
|
||||||
menuHandler.rootItem.setAction (rootDirectoryAction);
|
menuHandler.rootItem.setAction (rootDirectoryAction);
|
||||||
menuHandler.showCatalogItem.setAction (hideCatalogAction);
|
menuHandler.showCatalogItem.setAction (hideCatalogAction);
|
||||||
@ -144,10 +144,12 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
menuHandler.duplicateItem.setAction (duplicateAction);
|
menuHandler.duplicateItem.setAction (duplicateAction);
|
||||||
menuHandler.closeTabItem.setAction (closeTabAction);
|
menuHandler.closeTabItem.setAction (closeTabAction);
|
||||||
|
|
||||||
addQuitListener (rootDirectoryAction);
|
showFreeAction.addPropertyChangeListener (diskLayoutPanel);
|
||||||
addQuitListener (menuHandler);
|
|
||||||
addQuitListener (catalogPanel);
|
quitListeners.add (rootDirectoryAction);
|
||||||
addQuitListener (this);
|
quitListeners.add (menuHandler);
|
||||||
|
quitListeners.add (catalogPanel);
|
||||||
|
quitListeners.add (this);
|
||||||
|
|
||||||
if (Desktop.isDesktopSupported ())
|
if (Desktop.isDesktopSupported ())
|
||||||
{
|
{
|
||||||
@ -158,14 +160,14 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
"Author - Denis Molony\nGitHub - https://github.com/dmolony/DiskBrowser",
|
"Author - Denis Molony\nGitHub - https://github.com/dmolony/DiskBrowser",
|
||||||
"About DiskBrowser", JOptionPane.INFORMATION_MESSAGE));
|
"About DiskBrowser", JOptionPane.INFORMATION_MESSAGE));
|
||||||
|
|
||||||
if (desktop.isSupported (Desktop.Action.APP_PREFERENCES) && false)
|
// if (desktop.isSupported (Desktop.Action.APP_PREFERENCES) && false)
|
||||||
desktop.setPreferencesHandler (
|
// desktop.setPreferencesHandler (
|
||||||
e -> JOptionPane.showMessageDialog (null, "Preferences dialog"));
|
// e -> JOptionPane.showMessageDialog (null, "Preferences dialog"));
|
||||||
|
|
||||||
if (desktop.isSupported (Desktop.Action.APP_QUIT_HANDLER))
|
if (desktop.isSupported (Desktop.Action.APP_QUIT_HANDLER))
|
||||||
desktop.setQuitHandler ( (e, r) -> fireQuitEvent ());
|
desktop.setQuitHandler ( (e, r) -> fireQuitEvent ()); // needed for cmd-Q
|
||||||
// else
|
// else
|
||||||
setQuitHandler ();
|
setQuitHandler (); // needed for the close button
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -185,9 +187,9 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
|
|
||||||
// Remove the two optional panels if they were previously hidden
|
// Remove the two optional panels if they were previously hidden
|
||||||
if (!menuHandler.showLayoutItem.isSelected ())
|
if (!menuHandler.showLayoutItem.isSelected ())
|
||||||
hideLayoutAction.set (false);
|
setLayoutPanel (false);
|
||||||
if (!menuHandler.showCatalogItem.isSelected ())
|
if (!menuHandler.showCatalogItem.isSelected ())
|
||||||
hideCatalogAction.set (false);
|
setCatalogPanel (false);
|
||||||
|
|
||||||
menuHandler.addBasicPreferencesListener (dataPanel);
|
menuHandler.addBasicPreferencesListener (dataPanel);
|
||||||
menuHandler.addAssemblerPreferencesListener (dataPanel);
|
menuHandler.addAssemblerPreferencesListener (dataPanel);
|
||||||
@ -209,7 +211,6 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
fireQuitEvent ();
|
fireQuitEvent ();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -224,13 +225,47 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void propertyChange (PropertyChangeEvent evt)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (evt.getSource () == hideCatalogAction)
|
||||||
|
setCatalogPanel ((boolean) evt.getNewValue ());
|
||||||
|
else if (evt.getSource () == hideLayoutAction)
|
||||||
|
setLayoutPanel ((boolean) evt.getNewValue ());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private void setCatalogPanel (boolean show)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (show)
|
||||||
|
add (catalogBorderPanel, BorderLayout.WEST);
|
||||||
|
else
|
||||||
|
remove (catalogBorderPanel);
|
||||||
|
|
||||||
|
validate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private void setLayoutPanel (boolean show)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (show)
|
||||||
|
add (layoutBorderPanel, BorderLayout.EAST);
|
||||||
|
else
|
||||||
|
remove (layoutBorderPanel);
|
||||||
|
|
||||||
|
validate ();
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public void diskSelected (DiskSelectedEvent e)
|
public void diskSelected (DiskSelectedEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
setTitle (windowTitle + e.getFormattedDisk () == null ? ""
|
setTitle (windowTitle + e.getFormattedDisk () == null ? "" : e.getFormattedDisk ().getName ());
|
||||||
: e.getFormattedDisk ().getName ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -250,31 +285,15 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
windowSaver.restoreWindow ();
|
windowSaver.restoreWindow ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
public static void main (String[] args)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
DiskBrowser.args = args;
|
|
||||||
EventQueue.invokeLater (new Runnable ()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run ()
|
|
||||||
{
|
|
||||||
setLookAndFeel ();
|
|
||||||
new DiskBrowser ().setVisible (true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private static void setLookAndFeel ()
|
private static void setLookAndFeel ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
// FlatLightLaf.install ();
|
// FlatLightLaf.install ();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
|
UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
|
||||||
// UIManager.setLookAndFeel (new FlatLightLaf ());
|
// UIManager.setLookAndFeel (new FlatLightLaf ());
|
||||||
if (MAC)
|
if (MAC)
|
||||||
System.setProperty ("apple.laf.useScreenMenuBar", "true");
|
System.setProperty ("apple.laf.useScreenMenuBar", "true");
|
||||||
}
|
}
|
||||||
@ -284,22 +303,6 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<QuitListener> quitListeners = new ArrayList<> ();
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
public void addQuitListener (QuitListener listener)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
quitListeners.add (listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
public void removeQuitListener (QuitListener listener)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
quitListeners.remove (listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private void fireQuitEvent ()
|
private void fireQuitEvent ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -317,4 +320,20 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
for (QuitListener listener : quitListeners)
|
for (QuitListener listener : quitListeners)
|
||||||
listener.restore (prefs);
|
listener.restore (prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public static void main (String[] args)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
DiskBrowser.args = args;
|
||||||
|
EventQueue.invokeLater (new Runnable ()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
|
setLookAndFeel ();
|
||||||
|
new DiskBrowser ().setVisible (true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -97,9 +97,10 @@ class DiskLayoutImage extends DiskPanel implements Scrollable, RedoListener
|
|||||||
selectionHandler.setSelection (sectors);
|
selectionHandler.setSelection (sectors);
|
||||||
if (sectors != null && sectors.size () > 0)
|
if (sectors != null && sectors.size () > 0)
|
||||||
{
|
{
|
||||||
DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1);
|
// DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1);
|
||||||
if (da != null)
|
// if (da != null)
|
||||||
scrollRectToVisible (layoutDetails.getLocation (da));
|
// scrollRectToVisible (layoutDetails.getLocation (da));
|
||||||
|
scrollRectToVisible (layoutDetails.getLocation (sectors.get (0)));
|
||||||
}
|
}
|
||||||
repaint ();
|
repaint ();
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
@ -19,14 +21,14 @@ import javax.swing.JScrollPane;
|
|||||||
|
|
||||||
import com.bytezone.diskbrowser.disk.Disk;
|
import com.bytezone.diskbrowser.disk.Disk;
|
||||||
import com.bytezone.diskbrowser.disk.DiskAddress;
|
import com.bytezone.diskbrowser.disk.DiskAddress;
|
||||||
import com.bytezone.diskbrowser.disk.HybridDisk;
|
|
||||||
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
||||||
|
import com.bytezone.diskbrowser.disk.HybridDisk;
|
||||||
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
|
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
|
||||||
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
|
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class DiskLayoutPanel extends JPanel
|
class DiskLayoutPanel extends JPanel implements DiskSelectionListener,
|
||||||
implements DiskSelectionListener, FileSelectionListener, RedoListener
|
FileSelectionListener, RedoListener, PropertyChangeListener
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final int SIZE = 15; // basic unit of a display block
|
private static final int SIZE = 15; // basic unit of a display block
|
||||||
@ -134,6 +136,14 @@ class DiskLayoutPanel extends JPanel
|
|||||||
diskLayoutImage.setShowFreeSectors (free);
|
diskLayoutImage.setShowFreeSectors (free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void propertyChange (PropertyChangeEvent evt)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
setFree ((Boolean) evt.getNewValue ());
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void addSectorSelectionListener (SectorSelectionListener listener)
|
public void addSectorSelectionListener (SectorSelectionListener listener)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -141,6 +151,14 @@ class DiskLayoutPanel extends JPanel
|
|||||||
diskLayoutImage.addSectorSelectionListener (listener);
|
diskLayoutImage.addSectorSelectionListener (listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void addSectorSelectionListener (SectorSelectionListener... listeners)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
for (SectorSelectionListener sectorSelectionListener : listeners)
|
||||||
|
diskLayoutImage.addSectorSelectionListener (sectorSelectionListener);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void removeSectorSelectionListener (SectorSelectionListener listener)
|
public void removeSectorSelectionListener (SectorSelectionListener listener)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -244,8 +262,8 @@ class DiskLayoutPanel extends JPanel
|
|||||||
|
|
||||||
private void checkCorrectDisk (FormattedDisk newDisk)
|
private void checkCorrectDisk (FormattedDisk newDisk)
|
||||||
{
|
{
|
||||||
if (newDisk instanceof HybridDisk)
|
if (newDisk instanceof HybridDisk hybridDisk)
|
||||||
newDisk = ((HybridDisk) newDisk).getCurrentDisk (); // never set to a Dual-dos disk
|
newDisk = hybridDisk.getCurrentDisk (); // never set to a hybrid disk
|
||||||
if (newDisk != diskLayoutImage.getDisk ())
|
if (newDisk != diskLayoutImage.getDisk ())
|
||||||
{
|
{
|
||||||
LayoutDetails layout = new LayoutDetails (newDisk);
|
LayoutDetails layout = new LayoutDetails (newDisk);
|
||||||
|
@ -157,6 +157,7 @@ class DiskLayoutSelection implements Iterable<DiskAddress>
|
|||||||
for (DiskAddress selection : highlights)
|
for (DiskAddress selection : highlights)
|
||||||
if (selection != null && da.matches (selection))
|
if (selection != null && da.matches (selection))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,14 +85,13 @@ class DiskLegendPanel extends DiskPanel
|
|||||||
int val = formattedDisk.falseNegativeBlocks ();
|
int val = formattedDisk.falseNegativeBlocks ();
|
||||||
if (val > 0)
|
if (val > 0)
|
||||||
{
|
{
|
||||||
g.drawString (
|
g.drawString (val + " unused sector" + (val == 1 ? "" : "s") //
|
||||||
val + " unused sector" + (val == 1 ? "" : "s") + " marked as unavailable", 10,
|
+ " marked as unavailable", 10, y);
|
||||||
y);
|
|
||||||
y += lineHeight;
|
y += lineHeight;
|
||||||
}
|
}
|
||||||
val = formattedDisk.falsePositiveBlocks ();
|
val = formattedDisk.falsePositiveBlocks ();
|
||||||
if (val > 0)
|
if (val > 0)
|
||||||
g.drawString (val + " used sector" + (val == 1 ? "" : "s") + " marked as available",
|
g.drawString (val + " used sector" + (val == 1 ? "" : "s") //
|
||||||
10, y);
|
+ " marked as available", 10, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,6 +13,7 @@ public class DiskPanel extends JPanel
|
|||||||
{
|
{
|
||||||
FormattedDisk formattedDisk;
|
FormattedDisk formattedDisk;
|
||||||
LayoutDetails layoutDetails;
|
LayoutDetails layoutDetails;
|
||||||
|
|
||||||
int blockWidth = 30; // default
|
int blockWidth = 30; // default
|
||||||
int blockHeight = 15; // default
|
int blockHeight = 15; // default
|
||||||
int centerOffset;
|
int centerOffset;
|
||||||
@ -20,11 +21,11 @@ public class DiskPanel extends JPanel
|
|||||||
Color backgroundColor = new Color (0xE0, 0xE0, 0xE0);
|
Color backgroundColor = new Color (0xE0, 0xE0, 0xE0);
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void setDisk (FormattedDisk disk, LayoutDetails details)
|
public void setDisk (FormattedDisk formattedDisk, LayoutDetails layoutDetails)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
formattedDisk = disk;
|
this.formattedDisk = formattedDisk;
|
||||||
layoutDetails = details;
|
this.layoutDetails = layoutDetails;
|
||||||
|
|
||||||
blockWidth = layoutDetails.block.width;
|
blockWidth = layoutDetails.block.width;
|
||||||
blockHeight = layoutDetails.block.height;
|
blockHeight = layoutDetails.block.height;
|
||||||
|
@ -9,7 +9,7 @@ import com.bytezone.diskbrowser.disk.FormattedDisk;
|
|||||||
class DiskSelectedEvent extends EventObject
|
class DiskSelectedEvent extends EventObject
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final FormattedDisk owner;
|
private final FormattedDisk formattedDisk;
|
||||||
boolean redo;
|
boolean redo;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -17,14 +17,14 @@ class DiskSelectedEvent extends EventObject
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super (source);
|
super (source);
|
||||||
this.owner = disk;
|
this.formattedDisk = disk;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public FormattedDisk getFormattedDisk ()
|
public FormattedDisk getFormattedDisk ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return owner;
|
return formattedDisk;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -32,14 +32,14 @@ class DiskSelectedEvent extends EventObject
|
|||||||
public String toString ()
|
public String toString ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return owner.getDisk ().getFile ().getAbsolutePath ();
|
return formattedDisk.getDisk ().getFile ().getAbsolutePath ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public String toText ()
|
public String toText ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return owner.getAbsolutePath ();
|
return formattedDisk.getAbsolutePath ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -3,6 +3,8 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
@ -14,7 +16,7 @@ import com.bytezone.diskbrowser.duplicates.RootFolderData;
|
|||||||
import com.bytezone.diskbrowser.utilities.DefaultAction;
|
import com.bytezone.diskbrowser.utilities.DefaultAction;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class DuplicateAction extends DefaultAction implements RootDirectoryChangeListener
|
public class DuplicateAction extends DefaultAction implements PropertyChangeListener
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
RootFolderData rootFolderData;
|
RootFolderData rootFolderData;
|
||||||
@ -36,14 +38,22 @@ public class DuplicateAction extends DefaultAction implements RootDirectoryChang
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
private void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
|
||||||
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
assert rootFolderData.getRootFolder () == newRootFolder;
|
assert rootFolderData.getRootFolder () == newRootFolder;
|
||||||
setEnabled (rootFolderData.getRootFolder () != null);
|
setEnabled (rootFolderData.getRootFolder () != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void propertyChange (PropertyChangeEvent evt)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (evt.getPropertyName ().equals ("RootDirectory"))
|
||||||
|
rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ());
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed (ActionEvent arg0)
|
public void actionPerformed (ActionEvent arg0)
|
||||||
|
@ -3,8 +3,8 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
||||||
import com.bytezone.diskbrowser.disk.HybridDisk;
|
|
||||||
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
||||||
|
import com.bytezone.diskbrowser.disk.HybridDisk;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class FileSelectedEvent extends EventObject
|
class FileSelectedEvent extends EventObject
|
||||||
@ -21,8 +21,9 @@ class FileSelectedEvent extends EventObject
|
|||||||
super (source);
|
super (source);
|
||||||
this.appleFileSource = appleFileSource;
|
this.appleFileSource = appleFileSource;
|
||||||
|
|
||||||
// If a file is selected from a disk which is contained in a Dual-dos disk, then the DDS
|
// If a file is selected from a disk which is part of a hybrid disk, then the
|
||||||
// must be told so that it can ensure its internal currentDisk is set correctly
|
// parent must be told so that it can ensure its internal currentDisk is set
|
||||||
|
// correctly
|
||||||
FormattedDisk fd = appleFileSource.getFormattedDisk ();
|
FormattedDisk fd = appleFileSource.getFormattedDisk ();
|
||||||
HybridDisk ddd = (HybridDisk) fd.getParent ();
|
HybridDisk ddd = (HybridDisk) fd.getParent ();
|
||||||
if (ddd != null)
|
if (ddd != null)
|
||||||
|
@ -36,6 +36,7 @@ public class FontAction extends DefaultAction implements QuitListener
|
|||||||
{
|
{
|
||||||
super ("Set Font...", "Set display to a different font or font size",
|
super ("Set Font...", "Set display to a different font or font size",
|
||||||
"/com/bytezone/loadlister/");
|
"/com/bytezone/loadlister/");
|
||||||
|
|
||||||
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
|
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_F, mask));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_F, mask));
|
||||||
}
|
}
|
||||||
@ -146,8 +147,7 @@ public class FontAction extends DefaultAction implements QuitListener
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
FontChangeEvent fontChangeEvent = new FontChangeEvent (font);
|
FontChangeEvent fontChangeEvent = new FontChangeEvent (font);
|
||||||
FontChangeListener[] listeners =
|
FontChangeListener[] listeners = (listenerList.getListeners (FontChangeListener.class));
|
||||||
(listenerList.getListeners (FontChangeListener.class));
|
|
||||||
for (FontChangeListener listener : listeners)
|
for (FontChangeListener listener : listeners)
|
||||||
listener.changeFont (fontChangeEvent);
|
listener.changeFont (fontChangeEvent);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ public class FontFrame extends JFrame
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Font Selection");
|
super ("Font Selection");
|
||||||
|
|
||||||
this.fontAction = fontAction;
|
this.fontAction = fontAction;
|
||||||
buildLayout ();
|
buildLayout ();
|
||||||
getFonts ();
|
getFonts ();
|
||||||
@ -96,8 +97,7 @@ public class FontFrame extends JFrame
|
|||||||
public String getSelectedValue ()
|
public String getSelectedValue ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
String fontName = fontList.getSelectedValue ();
|
return fontList.getSelectedValue ();
|
||||||
return fontName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -112,8 +112,7 @@ public class FontFrame extends JFrame
|
|||||||
public String getSelectedSize ()
|
public String getSelectedSize ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
String fontSize = fontSizePanel.getSelectedText ();
|
return fontSizePanel.getSelectedText ();
|
||||||
return fontSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -146,7 +145,6 @@ public class FontFrame extends JFrame
|
|||||||
|
|
||||||
int ptr = 0;
|
int ptr = 0;
|
||||||
for (String fontName : fonts)
|
for (String fontName : fonts)
|
||||||
{
|
|
||||||
while (ptr < pf.length)
|
while (ptr < pf.length)
|
||||||
{
|
{
|
||||||
int result = fontName.compareToIgnoreCase (pf[ptr]);
|
int result = fontName.compareToIgnoreCase (pf[ptr]);
|
||||||
@ -159,7 +157,6 @@ public class FontFrame extends JFrame
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fontList.setSelectedValue (initialFont, true);
|
fontList.setSelectedValue (initialFont, true);
|
||||||
}
|
}
|
||||||
@ -254,13 +251,14 @@ public class FontFrame extends JFrame
|
|||||||
private Font getCurrentFont ()
|
private Font getCurrentFont ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
String fontName = getSelectedValue ();
|
|
||||||
String fontSize = getSelectedSize ();
|
String fontSize = getSelectedSize ();
|
||||||
if (fontSize.isEmpty ())
|
if (fontSize.isEmpty ())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
int pos = fontSize.indexOf (' ');
|
int pos = fontSize.indexOf (' ');
|
||||||
int size = Integer.parseInt (fontSize.substring (0, pos));
|
int size = Integer.parseInt (fontSize.substring (0, pos));
|
||||||
return new Font (fontName, Font.PLAIN, size);
|
|
||||||
|
return new Font (getSelectedValue (), Font.PLAIN, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -269,8 +267,10 @@ public class FontFrame extends JFrame
|
|||||||
{
|
{
|
||||||
initialFont = getSelectedValue ();
|
initialFont = getSelectedValue ();
|
||||||
initialSize = getSelectedSize ();
|
initialSize = getSelectedSize ();
|
||||||
|
|
||||||
int pos = initialSize.indexOf (' ');
|
int pos = initialSize.indexOf (' ');
|
||||||
int size = Integer.parseInt (initialSize.substring (0, pos));
|
int size = Integer.parseInt (initialSize.substring (0, pos));
|
||||||
|
|
||||||
Font font = new Font (initialFont, Font.PLAIN, size);
|
Font font = new Font (initialFont, Font.PLAIN, size);
|
||||||
fontAction.fireFontChangeEvent (font);
|
fontAction.fireFontChangeEvent (font);
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,26 @@
|
|||||||
package com.bytezone.diskbrowser.gui;
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class HideCatalogAction extends AbstractAction
|
class HideCatalogAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
JFrame owner;
|
|
||||||
JPanel catalogPanel;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public HideCatalogAction (JFrame owner, JPanel catalogPanel)
|
public HideCatalogAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Show catalog panel");
|
super ("Show catalog panel");
|
||||||
|
|
||||||
putValue (Action.SHORT_DESCRIPTION, "Show/hide the catalog panel");
|
putValue (Action.SHORT_DESCRIPTION, "Show/hide the catalog panel");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt C"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt C"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_C);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_C);
|
||||||
this.owner = owner;
|
|
||||||
this.catalogPanel = catalogPanel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -35,22 +28,7 @@ class HideCatalogAction extends AbstractAction
|
|||||||
public void actionPerformed (ActionEvent e)
|
public void actionPerformed (ActionEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
set (((JMenuItem) e.getSource ()).isSelected ());
|
firePropertyChange (e.getActionCommand (), null,
|
||||||
}
|
((JMenuItem) e.getSource ()).isSelected ());
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
public void set (boolean show)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
if (show)
|
|
||||||
{
|
|
||||||
owner.add (catalogPanel, BorderLayout.WEST);
|
|
||||||
owner.validate ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
owner.remove (catalogPanel);
|
|
||||||
owner.validate ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,33 +1,26 @@
|
|||||||
package com.bytezone.diskbrowser.gui;
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class HideLayoutAction extends AbstractAction
|
class HideLayoutAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
JFrame owner;
|
|
||||||
JPanel layoutPanel;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public HideLayoutAction (JFrame owner, JPanel layoutPanel)
|
public HideLayoutAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Show disk layout panel");
|
super ("Show disk layout panel");
|
||||||
|
|
||||||
putValue (Action.SHORT_DESCRIPTION, "Show/hide the disk layout panel");
|
putValue (Action.SHORT_DESCRIPTION, "Show/hide the disk layout panel");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt D"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt D"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_D);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_D);
|
||||||
this.owner = owner;
|
|
||||||
this.layoutPanel = layoutPanel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -35,22 +28,7 @@ class HideLayoutAction extends AbstractAction
|
|||||||
public void actionPerformed (ActionEvent e)
|
public void actionPerformed (ActionEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
set (((JMenuItem) e.getSource ()).isSelected ());
|
firePropertyChange (e.getActionCommand (), null,
|
||||||
}
|
((JMenuItem) e.getSource ()).isSelected ());
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
public void set (boolean show)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
if (show)
|
|
||||||
{
|
|
||||||
owner.add (layoutPanel, BorderLayout.EAST);
|
|
||||||
owner.validate ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
owner.remove (layoutPanel);
|
|
||||||
owner.validate ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
84
src/com/bytezone/diskbrowser/gui/ImagePanel.java
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
public class ImagePanel extends JPanel
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
private static final int BACKGROUND = 245;
|
||||||
|
|
||||||
|
private BufferedImage image;
|
||||||
|
private double scale = 1;
|
||||||
|
private double userScale = .5;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public ImagePanel ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
this.setBackground (new Color (BACKGROUND, BACKGROUND, BACKGROUND));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void setScale (double scale)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
this.userScale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public void setImage (BufferedImage image)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
this.image = image;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
Graphics2D g2 = image.createGraphics ();
|
||||||
|
g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
width = image.getWidth ();
|
||||||
|
height = image.getHeight ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
width = height = 0;
|
||||||
|
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
if (width < 400 && width > 0)
|
||||||
|
scale = (400 - 1) / width + 1;
|
||||||
|
else
|
||||||
|
scale = 1;
|
||||||
|
if (scale > 4)
|
||||||
|
scale = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
scale *= userScale;
|
||||||
|
|
||||||
|
setPreferredSize (new Dimension ((int) (width * scale), (int) (height * scale)));
|
||||||
|
repaint ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void paintComponent (Graphics g)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
super.paintComponent (g);
|
||||||
|
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
Graphics2D g2 = ((Graphics2D) g);
|
||||||
|
g2.transform (AffineTransform.getScaleInstance (scale, scale));
|
||||||
|
g2.drawImage (image, (int) ((getWidth () - image.getWidth () * scale) / 2 / scale), 4, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,45 +2,33 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JTextArea;
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class LineWrapAction extends AbstractAction
|
class LineWrapAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
List<JTextArea> listeners = new ArrayList<> ();
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public LineWrapAction ()
|
public LineWrapAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Line wrap");
|
super ("Line wrap");
|
||||||
putValue (Action.SHORT_DESCRIPTION, "Print the contents of the output panel");
|
|
||||||
|
putValue (Action.SHORT_DESCRIPTION, "Wrap/don't wrap the text in the output panel");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt W"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt W"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_W);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
public void addListener (JTextArea listener)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
if (!listeners.contains (listener))
|
|
||||||
listeners.add (listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed (ActionEvent e)
|
public void actionPerformed (ActionEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
for (JTextArea listener : listeners)
|
firePropertyChange (e.getActionCommand (), null,
|
||||||
listener.setLineWrap (((JMenuItem) e.getSource ()).isSelected ());
|
((JMenuItem) e.getSource ()).isSelected ());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -76,7 +76,6 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
|
|
||||||
private static final String PREFS_PALETTE = "palette";
|
private static final String PREFS_PALETTE = "palette";
|
||||||
|
|
||||||
FormattedDisk currentDisk;
|
|
||||||
final SaveDiskAction saveDiskAction = new SaveDiskAction ();
|
final SaveDiskAction saveDiskAction = new SaveDiskAction ();
|
||||||
final SaveFileAction saveFileAction = new SaveFileAction ();
|
final SaveFileAction saveFileAction = new SaveFileAction ();
|
||||||
final SaveSectorsAction saveSectorsAction = new SaveSectorsAction ();
|
final SaveSectorsAction saveSectorsAction = new SaveSectorsAction ();
|
||||||
@ -186,6 +185,8 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
|
|
||||||
ButtonGroup paletteGroup = new ButtonGroup ();
|
ButtonGroup paletteGroup = new ButtonGroup ();
|
||||||
|
|
||||||
|
FormattedDisk currentDisk;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
MenuHandler ()
|
MenuHandler ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -211,7 +212,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
addLauncherMenu ();
|
addLauncherMenu ();
|
||||||
|
|
||||||
fileMenu.add (printItem);
|
fileMenu.add (printItem);
|
||||||
// fileMenu.addSeparator ();
|
// fileMenu.addSeparator ();
|
||||||
fileMenu.add (closeTabItem);
|
fileMenu.add (closeTabItem);
|
||||||
|
|
||||||
JMenuItem fontItem = new JMenuItem (fontAction);
|
JMenuItem fontItem = new JMenuItem (fontAction);
|
||||||
@ -270,13 +271,13 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
applesoftMenu.add (splitRemarkItem);
|
applesoftMenu.add (splitRemarkItem);
|
||||||
applesoftMenu.add (splitDimItem);
|
applesoftMenu.add (splitDimItem);
|
||||||
applesoftMenu.add (alignAssignItem);
|
applesoftMenu.add (alignAssignItem);
|
||||||
// applesoftMenu.add (showBasicTargetsItem);
|
// applesoftMenu.add (showBasicTargetsItem);
|
||||||
// applesoftMenu.add (onlyShowTargetLinesItem);
|
// applesoftMenu.add (onlyShowTargetLinesItem);
|
||||||
applesoftMenu.add (showCaretItem);
|
applesoftMenu.add (showCaretItem);
|
||||||
applesoftMenu.add (showThenItem);
|
applesoftMenu.add (showThenItem);
|
||||||
applesoftMenu.add (blankAfterReturnItem);
|
applesoftMenu.add (blankAfterReturnItem);
|
||||||
applesoftMenu.add (formatRemItem);
|
applesoftMenu.add (formatRemItem);
|
||||||
// applesoftMenu.add (deleteExtraRemSpace);
|
// applesoftMenu.add (deleteExtraRemSpace);
|
||||||
applesoftMenu.add (deleteExtraDataSpace);
|
applesoftMenu.add (deleteExtraDataSpace);
|
||||||
applesoftMenu.addSeparator ();
|
applesoftMenu.addSeparator ();
|
||||||
applesoftMenu.add (showXrefItem);
|
applesoftMenu.add (showXrefItem);
|
||||||
@ -284,7 +285,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
applesoftMenu.add (showSymbolsItem);
|
applesoftMenu.add (showSymbolsItem);
|
||||||
applesoftMenu.add (showFunctionsItem);
|
applesoftMenu.add (showFunctionsItem);
|
||||||
applesoftMenu.add (showConstantsItem);
|
applesoftMenu.add (showConstantsItem);
|
||||||
// applesoftMenu.add (listStringsItem);
|
// applesoftMenu.add (listStringsItem);
|
||||||
applesoftMenu.add (showDuplicateSymbolsItem);
|
applesoftMenu.add (showDuplicateSymbolsItem);
|
||||||
|
|
||||||
assemblerMenu.add (showAssemblerHeaderItem);
|
assemblerMenu.add (showAssemblerHeaderItem);
|
||||||
@ -347,6 +348,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
showAllFormatItem.addActionListener (basicPreferencesAction);
|
showAllFormatItem.addActionListener (basicPreferencesAction);
|
||||||
showAllXrefItem.addActionListener (basicPreferencesAction);
|
showAllXrefItem.addActionListener (basicPreferencesAction);
|
||||||
appleLineWrapItem.addActionListener (basicPreferencesAction);
|
appleLineWrapItem.addActionListener (basicPreferencesAction);
|
||||||
|
|
||||||
for (JMenuItem item : applesoftFormatItems)
|
for (JMenuItem item : applesoftFormatItems)
|
||||||
item.addActionListener (basicPreferencesAction);
|
item.addActionListener (basicPreferencesAction);
|
||||||
for (JMenuItem item : applesoftXrefItems)
|
for (JMenuItem item : applesoftXrefItems)
|
||||||
@ -374,10 +376,12 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
|
|
||||||
sectorGroup.add (sector256Item);
|
sectorGroup.add (sector256Item);
|
||||||
sectorGroup.add (sector512Item);
|
sectorGroup.add (sector512Item);
|
||||||
|
|
||||||
interleaveGroup.add (interleave0Item);
|
interleaveGroup.add (interleave0Item);
|
||||||
interleaveGroup.add (interleave1Item);
|
interleaveGroup.add (interleave1Item);
|
||||||
interleaveGroup.add (interleave2Item);
|
interleaveGroup.add (interleave2Item);
|
||||||
interleaveGroup.add (interleave3Item);
|
interleaveGroup.add (interleave3Item);
|
||||||
|
|
||||||
scaleGroup.add (scale1Item);
|
scaleGroup.add (scale1Item);
|
||||||
scaleGroup.add (scale2Item);
|
scaleGroup.add (scale2Item);
|
||||||
scaleGroup.add (scale3Item);
|
scaleGroup.add (scale3Item);
|
||||||
@ -546,6 +550,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
openSupported = true;
|
openSupported = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!openSupported)
|
if (!openSupported)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -554,60 +559,6 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
fileMenu.addSeparator ();
|
fileMenu.addSeparator ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
@Override
|
|
||||||
public void quit (Preferences prefs)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
prefs.putBoolean (PREFS_LINE_WRAP, lineWrapItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_LAYOUT, showLayoutItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_CATALOG, showCatalogItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_FREE_SECTORS, showFreeSectorsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_COLOUR_QUIRKS, colourQuirksItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_MONOCHROME, monochromeItem.isSelected ());
|
|
||||||
prefs.putInt (PREFS_PALETTE,
|
|
||||||
HiResImage.getPaletteFactory ().getCurrentPaletteIndex ());
|
|
||||||
fontAction.quit (prefs);
|
|
||||||
|
|
||||||
int scale = scale1Item.isSelected () ? 1 : scale2Item.isSelected () ? 2 : 3;
|
|
||||||
prefs.putInt (PREFS_SCALE, scale);
|
|
||||||
|
|
||||||
prefs.putBoolean (PREFS_SHOW_HEADER, showHeaderItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_ALL_FORMAT, showAllFormatItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_ALL_XREF, showAllXrefItem.isSelected ());
|
|
||||||
|
|
||||||
prefs.putBoolean (PREFS_APPLE_LINE_WRAP, appleLineWrapItem.isSelected ());
|
|
||||||
|
|
||||||
prefs.putBoolean (PREFS_SPLIT_REMARKS, splitRemarkItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SPLIT_DIM, splitDimItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_ALIGN_ASSIGN, alignAssignItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_CARET, showCaretItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_THEN, showThenItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_BLANK_AFTER_RETURN, blankAfterReturnItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_FORMAT_REM, formatRemItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_DELETE_EXTRA_DATA_SPACE, deleteExtraDataSpace.isSelected ());
|
|
||||||
|
|
||||||
prefs.putBoolean (PREFS_SHOW_GOSUB_GOTO, showXrefItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_CALLS, showCallsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_SYMBOLS, showSymbolsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_FUNCTIONS, showFunctionsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_CONSTANTS, showConstantsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_DUPLICATE_SYMBOLS,
|
|
||||||
showDuplicateSymbolsItem.isSelected ());
|
|
||||||
|
|
||||||
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_TARGETS,
|
|
||||||
showAssemblerTargetsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_STRINGS,
|
|
||||||
showAssemblerStringsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_HEADER, showAssemblerHeaderItem.isSelected ());
|
|
||||||
|
|
||||||
prefs.putBoolean (PREFS_PRODOS_SORT_DIRECTORIES,
|
|
||||||
prodosSortDirectoriesItem.isSelected ());
|
|
||||||
|
|
||||||
prefs.putBoolean (PREFS_TEXT_SHOW_OFFSETS, showTextOffsetsItem.isSelected ());
|
|
||||||
prefs.putBoolean (PREFS_TEXT_SHOW_HEADER, showTextHeaderItem.isSelected ());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public void restore (Preferences prefs)
|
public void restore (Preferences prefs)
|
||||||
@ -697,6 +648,60 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
fontAction.restore (prefs);
|
fontAction.restore (prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void quit (Preferences prefs)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
prefs.putBoolean (PREFS_LINE_WRAP, lineWrapItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_LAYOUT, showLayoutItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_CATALOG, showCatalogItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_FREE_SECTORS, showFreeSectorsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_COLOUR_QUIRKS, colourQuirksItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_MONOCHROME, monochromeItem.isSelected ());
|
||||||
|
prefs.putInt (PREFS_PALETTE,
|
||||||
|
HiResImage.getPaletteFactory ().getCurrentPaletteIndex ());
|
||||||
|
fontAction.quit (prefs);
|
||||||
|
|
||||||
|
int scale = scale1Item.isSelected () ? 1 : scale2Item.isSelected () ? 2 : 3;
|
||||||
|
prefs.putInt (PREFS_SCALE, scale);
|
||||||
|
|
||||||
|
prefs.putBoolean (PREFS_SHOW_HEADER, showHeaderItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_ALL_FORMAT, showAllFormatItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_ALL_XREF, showAllXrefItem.isSelected ());
|
||||||
|
|
||||||
|
prefs.putBoolean (PREFS_APPLE_LINE_WRAP, appleLineWrapItem.isSelected ());
|
||||||
|
|
||||||
|
prefs.putBoolean (PREFS_SPLIT_REMARKS, splitRemarkItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SPLIT_DIM, splitDimItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_ALIGN_ASSIGN, alignAssignItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_CARET, showCaretItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_THEN, showThenItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_BLANK_AFTER_RETURN, blankAfterReturnItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_FORMAT_REM, formatRemItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_DELETE_EXTRA_DATA_SPACE, deleteExtraDataSpace.isSelected ());
|
||||||
|
|
||||||
|
prefs.putBoolean (PREFS_SHOW_GOSUB_GOTO, showXrefItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_CALLS, showCallsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_SYMBOLS, showSymbolsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_FUNCTIONS, showFunctionsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_CONSTANTS, showConstantsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_DUPLICATE_SYMBOLS,
|
||||||
|
showDuplicateSymbolsItem.isSelected ());
|
||||||
|
|
||||||
|
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_TARGETS,
|
||||||
|
showAssemblerTargetsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_STRINGS,
|
||||||
|
showAssemblerStringsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_HEADER, showAssemblerHeaderItem.isSelected ());
|
||||||
|
|
||||||
|
prefs.putBoolean (PREFS_PRODOS_SORT_DIRECTORIES,
|
||||||
|
prodosSortDirectoriesItem.isSelected ());
|
||||||
|
|
||||||
|
prefs.putBoolean (PREFS_TEXT_SHOW_OFFSETS, showTextOffsetsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_TEXT_SHOW_HEADER, showTextHeaderItem.isSelected ());
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public void diskSelected (DiskSelectedEvent event)
|
public void diskSelected (DiskSelectedEvent event)
|
||||||
@ -733,7 +738,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL
|
|||||||
interleave3Item.setSelected (disk.getDisk ().getInterleave () == 3);
|
interleave3Item.setSelected (disk.getDisk ().getInterleave () == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isDataDisk = (disk instanceof DataDisk);
|
boolean isDataDisk = disk instanceof DataDisk;
|
||||||
|
|
||||||
sector256Item.setEnabled (isDataDisk);
|
sector256Item.setEnabled (isDataDisk);
|
||||||
sector512Item.setEnabled (isDataDisk);
|
sector512Item.setEnabled (isDataDisk);
|
||||||
|
@ -12,17 +12,15 @@ import javax.swing.KeyStroke;
|
|||||||
class MonochromeAction extends AbstractAction
|
class MonochromeAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final DataPanel owner;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
MonochromeAction (DataPanel owner)
|
MonochromeAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Monochrome");
|
super ("Monochrome");
|
||||||
|
|
||||||
putValue (Action.SHORT_DESCRIPTION, "Display image in monochrome or color");
|
putValue (Action.SHORT_DESCRIPTION, "Display image in monochrome or color");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt M"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt M"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_M);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_M);
|
||||||
this.owner = owner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -30,6 +28,7 @@ class MonochromeAction extends AbstractAction
|
|||||||
public void actionPerformed (ActionEvent e)
|
public void actionPerformed (ActionEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
owner.setMonochrome (((JMenuItem) e.getSource ()).isSelected ());
|
firePropertyChange (e.getActionCommand (), null,
|
||||||
|
((JMenuItem) e.getSource ()).isSelected ());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,11 +17,11 @@ import com.bytezone.diskbrowser.applefile.PaletteFactory.CycleDirection;
|
|||||||
class NextPaletteAction extends AbstractAction
|
class NextPaletteAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final DataPanel owner;
|
private final OutputPanel owner;
|
||||||
private final ButtonGroup buttonGroup;
|
private final ButtonGroup buttonGroup;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
NextPaletteAction (DataPanel owner, ButtonGroup buttonGroup)
|
NextPaletteAction (OutputPanel owner, ButtonGroup buttonGroup)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Next Palette");
|
super ("Next Palette");
|
||||||
|
@ -1,27 +1,21 @@
|
|||||||
package com.bytezone.diskbrowser.gui;
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.geom.AffineTransform;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
import javax.swing.ButtonGroup;
|
import javax.swing.ButtonGroup;
|
||||||
import javax.swing.JCheckBoxMenuItem;
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
import javax.swing.JTextArea;
|
import javax.swing.JTextArea;
|
||||||
import javax.swing.ScrollPaneConstants;
|
import javax.swing.ScrollPaneConstants;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingWorker;
|
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
@ -39,17 +33,18 @@ import com.bytezone.diskbrowser.disk.DiskAddress;
|
|||||||
import com.bytezone.diskbrowser.disk.SectorList;
|
import com.bytezone.diskbrowser.disk.SectorList;
|
||||||
import com.bytezone.diskbrowser.gui.FontAction.FontChangeEvent;
|
import com.bytezone.diskbrowser.gui.FontAction.FontChangeEvent;
|
||||||
import com.bytezone.diskbrowser.gui.FontAction.FontChangeListener;
|
import com.bytezone.diskbrowser.gui.FontAction.FontChangeListener;
|
||||||
|
import com.bytezone.diskbrowser.wizardry.MazeLevel;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class DataPanel extends JTabbedPane
|
public class OutputPanel extends JTabbedPane
|
||||||
implements DiskSelectionListener, FileSelectionListener, SectorSelectionListener,
|
implements DiskSelectionListener, FileSelectionListener, SectorSelectionListener,
|
||||||
FileNodeSelectionListener, FontChangeListener, BasicPreferencesListener,
|
FileNodeSelectionListener, FontChangeListener, BasicPreferencesListener,
|
||||||
AssemblerPreferencesListener, TextPreferencesListener
|
AssemblerPreferencesListener, TextPreferencesListener, PropertyChangeListener
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final int TEXT_WIDTH = 65;
|
private static final int TEXT_WIDTH = 65;
|
||||||
private static final int BACKGROUND = 245;
|
|
||||||
|
|
||||||
|
// final MenuHandler menuHandler;
|
||||||
private final JTextArea formattedText;
|
private final JTextArea formattedText;
|
||||||
private final JTextArea hexText;
|
private final JTextArea hexText;
|
||||||
private final JTextArea disassemblyText;
|
private final JTextArea disassemblyText;
|
||||||
@ -57,41 +52,42 @@ public class DataPanel extends JTabbedPane
|
|||||||
// these two panes are interchangeable
|
// these two panes are interchangeable
|
||||||
private final JScrollPane formattedPane;
|
private final JScrollPane formattedPane;
|
||||||
private final JScrollPane imagePane;
|
private final JScrollPane imagePane;
|
||||||
|
|
||||||
private boolean imageVisible = false;
|
private boolean imageVisible = false;
|
||||||
|
|
||||||
private final ImagePanel imagePanel; // internal class
|
private final ImagePanel imagePanel = new ImagePanel ();
|
||||||
|
private AnimationWorker animation;
|
||||||
private boolean debugMode;
|
private boolean debugMode;
|
||||||
|
private DataSource currentDataSource;
|
||||||
|
|
||||||
// used to determine whether the text has been set
|
// used to determine whether the text has been set
|
||||||
boolean formattedTextValid;
|
private boolean formattedTextValid;
|
||||||
boolean hexTextValid;
|
private boolean hexTextValid;
|
||||||
boolean assemblerTextValid;
|
private boolean assemblerTextValid;
|
||||||
DataSource currentDataSource;
|
|
||||||
|
|
||||||
private Worker animation;
|
private DebuggingAction debuggingAction = new DebuggingAction ();
|
||||||
|
private MonochromeAction monochromeAction = new MonochromeAction ();
|
||||||
|
private ColourQuirksAction colourQuirksAction = new ColourQuirksAction ();
|
||||||
|
private LineWrapAction lineWrapAction = new LineWrapAction ();
|
||||||
|
|
||||||
final MenuHandler menuHandler;
|
private enum TabType
|
||||||
|
|
||||||
enum TabType
|
|
||||||
{
|
{
|
||||||
FORMATTED, HEX, DISASSEMBLED
|
FORMATTED, HEX, DISASSEMBLED
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public DataPanel (MenuHandler mh)
|
public OutputPanel (MenuHandler menuHandler)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.menuHandler = mh;
|
|
||||||
setTabPlacement (SwingConstants.BOTTOM);
|
setTabPlacement (SwingConstants.BOTTOM);
|
||||||
|
|
||||||
formattedText = new JTextArea (10, TEXT_WIDTH);
|
formattedText = new JTextArea (10, TEXT_WIDTH);
|
||||||
formattedPane = setPanel (formattedText, "Formatted");
|
formattedPane = setPanel (formattedText, "Formatted");
|
||||||
// formattedText.setLineWrap (prefs.getBoolean (MenuHandler.PREFS_LINE_WRAP, true));
|
// formattedText.setLineWrap (prefs.getBoolean (MenuHandler.PREFS_LINE_WRAP, true));
|
||||||
formattedText.setText ("Please use the 'File->Set HOME folder...' command to "
|
formattedText.setText ("Please use the 'File->Set HOME folder...' command to "
|
||||||
+ "\ntell DiskBrowser where your Apple disks are located."
|
+ "\ntell DiskBrowser where your Apple disks are located."
|
||||||
+ "\n\nTo see the contents of a disk in more detail, double-click"
|
+ "\n\nTo see the contents of a disk in more detail, double-click"
|
||||||
+ "\nthe disk. You will then be able to select individual files to "
|
+ "\nthe disk. You will then be able to select individual files to " + "view them.");
|
||||||
+ "view completely.");
|
|
||||||
|
|
||||||
hexText = new JTextArea (10, TEXT_WIDTH);
|
hexText = new JTextArea (10, TEXT_WIDTH);
|
||||||
setPanel (hexText, "Hex dump");
|
setPanel (hexText, "Hex dump");
|
||||||
@ -99,10 +95,8 @@ public class DataPanel extends JTabbedPane
|
|||||||
disassemblyText = new JTextArea (10, TEXT_WIDTH);
|
disassemblyText = new JTextArea (10, TEXT_WIDTH);
|
||||||
setPanel (disassemblyText, "Disassembly");
|
setPanel (disassemblyText, "Disassembly");
|
||||||
|
|
||||||
imagePanel = new ImagePanel ();
|
imagePane = new JScrollPane (imagePanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
imagePane =
|
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
new JScrollPane (imagePanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
|
|
||||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
|
||||||
|
|
||||||
imagePane.setBorder (null);
|
imagePane.setBorder (null);
|
||||||
|
|
||||||
@ -126,6 +120,7 @@ public class DataPanel extends JTabbedPane
|
|||||||
formattedTextValid = true;
|
formattedTextValid = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // Hex
|
case 1: // Hex
|
||||||
if (!hexTextValid)
|
if (!hexTextValid)
|
||||||
{
|
{
|
||||||
@ -136,6 +131,7 @@ public class DataPanel extends JTabbedPane
|
|||||||
hexTextValid = true;
|
hexTextValid = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // Assembler
|
case 2: // Assembler
|
||||||
if (!assemblerTextValid)
|
if (!assemblerTextValid)
|
||||||
{
|
{
|
||||||
@ -146,19 +142,24 @@ public class DataPanel extends JTabbedPane
|
|||||||
assemblerTextValid = true;
|
assemblerTextValid = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.println ("Invalid index selected in DataPanel");
|
System.out.println ("Impossible - Invalid index selected in DataPanel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
LineWrapAction lineWrapAction = new LineWrapAction ();
|
|
||||||
menuHandler.lineWrapItem.setAction (lineWrapAction);
|
menuHandler.lineWrapItem.setAction (lineWrapAction);
|
||||||
lineWrapAction.addListener (formattedText);
|
lineWrapAction.addPropertyChangeListener (this);
|
||||||
|
|
||||||
menuHandler.colourQuirksItem.setAction (new ColourQuirksAction (this));
|
colourQuirksAction.addPropertyChangeListener (this);
|
||||||
menuHandler.monochromeItem.setAction (new MonochromeAction (this));
|
menuHandler.colourQuirksItem.setAction (colourQuirksAction);
|
||||||
menuHandler.debuggingItem.setAction (new DebuggingAction (this));
|
|
||||||
|
monochromeAction.addPropertyChangeListener (this);
|
||||||
|
menuHandler.monochromeItem.setAction (monochromeAction);
|
||||||
|
|
||||||
|
debuggingAction.addPropertyChangeListener (this);
|
||||||
|
menuHandler.debuggingItem.setAction (debuggingAction);
|
||||||
|
|
||||||
// fill in the placeholders created by the MenuHandler
|
// fill in the placeholders created by the MenuHandler
|
||||||
List<Palette> palettes = HiResImage.getPalettes ();
|
List<Palette> palettes = HiResImage.getPalettes ();
|
||||||
@ -170,6 +171,7 @@ public class DataPanel extends JTabbedPane
|
|||||||
JCheckBoxMenuItem item = (JCheckBoxMenuItem) enumeration.nextElement ();
|
JCheckBoxMenuItem item = (JCheckBoxMenuItem) enumeration.nextElement ();
|
||||||
item.setAction (new PaletteAction (this, palettes.get (ndx++)));
|
item.setAction (new PaletteAction (this, palettes.get (ndx++)));
|
||||||
}
|
}
|
||||||
|
|
||||||
menuHandler.nextPaletteItem.setAction (new NextPaletteAction (this, buttonGroup));
|
menuHandler.nextPaletteItem.setAction (new NextPaletteAction (this, buttonGroup));
|
||||||
menuHandler.prevPaletteItem.setAction (new PreviousPaletteAction (this, buttonGroup));
|
menuHandler.prevPaletteItem.setAction (new PreviousPaletteAction (this, buttonGroup));
|
||||||
}
|
}
|
||||||
@ -179,9 +181,8 @@ public class DataPanel extends JTabbedPane
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
HiResImage.getPaletteFactory ().setCurrentPalette (palette);
|
HiResImage.getPaletteFactory ().setCurrentPalette (palette);
|
||||||
if (currentDataSource instanceof HiResImage)
|
if (currentDataSource instanceof HiResImage image)
|
||||||
{
|
{
|
||||||
HiResImage image = (HiResImage) currentDataSource;
|
|
||||||
image.setPalette ();
|
image.setPalette ();
|
||||||
imagePanel.setImage (image.getImage ());
|
imagePanel.setImage (image.getImage ());
|
||||||
}
|
}
|
||||||
@ -192,15 +193,29 @@ public class DataPanel extends JTabbedPane
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
Palette palette = HiResImage.getPaletteFactory ().cyclePalette (direction);
|
Palette palette = HiResImage.getPaletteFactory ().cyclePalette (direction);
|
||||||
if (currentDataSource instanceof HiResImage)
|
if (currentDataSource instanceof HiResImage image)
|
||||||
{
|
{
|
||||||
HiResImage image = (HiResImage) currentDataSource;
|
|
||||||
image.setPalette ();
|
image.setPalette ();
|
||||||
imagePanel.setImage (image.getImage ());
|
imagePanel.setImage (image.getImage ());
|
||||||
}
|
}
|
||||||
return palette;
|
return palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public void propertyChange (PropertyChangeEvent evt)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (evt.getSource () == debuggingAction)
|
||||||
|
setDebug ((Boolean) evt.getNewValue ());
|
||||||
|
else if (evt.getSource () == monochromeAction)
|
||||||
|
setMonochrome ((Boolean) evt.getNewValue ());
|
||||||
|
else if (evt.getSource () == colourQuirksAction)
|
||||||
|
setColourQuirks ((Boolean) evt.getNewValue ());
|
||||||
|
else if (evt.getSource () == lineWrapAction)
|
||||||
|
setLineWrap ((Boolean) evt.getNewValue ());
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
void setLineWrap (boolean lineWrap)
|
void setLineWrap (boolean lineWrap)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -212,9 +227,8 @@ public class DataPanel extends JTabbedPane
|
|||||||
public void setColourQuirks (boolean value)
|
public void setColourQuirks (boolean value)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (currentDataSource instanceof HiResImage)
|
if (currentDataSource instanceof HiResImage image)
|
||||||
{
|
{
|
||||||
HiResImage image = (HiResImage) currentDataSource;
|
|
||||||
image.setColourQuirks (value);
|
image.setColourQuirks (value);
|
||||||
imagePanel.setImage (image.getImage ());
|
imagePanel.setImage (image.getImage ());
|
||||||
}
|
}
|
||||||
@ -224,9 +238,8 @@ public class DataPanel extends JTabbedPane
|
|||||||
public void setMonochrome (boolean value)
|
public void setMonochrome (boolean value)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (currentDataSource instanceof HiResImage)
|
if (currentDataSource instanceof HiResImage image)
|
||||||
{
|
{
|
||||||
HiResImage image = (HiResImage) currentDataSource;
|
|
||||||
image.setMonochrome (value);
|
image.setMonochrome (value);
|
||||||
imagePanel.setImage (image.getImage ());
|
imagePanel.setImage (image.getImage ());
|
||||||
}
|
}
|
||||||
@ -237,22 +250,16 @@ public class DataPanel extends JTabbedPane
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
imagePanel.setScale (scale);
|
imagePanel.setScale (scale);
|
||||||
if (currentDataSource instanceof HiResImage)
|
if (currentDataSource instanceof HiResImage image)
|
||||||
{
|
|
||||||
HiResImage image = (HiResImage) currentDataSource;
|
|
||||||
imagePanel.setImage (image.getImage ());
|
imagePanel.setImage (image.getImage ());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void update ()
|
public void update ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (currentDataSource instanceof HiResImage)
|
if (currentDataSource instanceof HiResImage image)
|
||||||
{
|
|
||||||
HiResImage image = (HiResImage) currentDataSource;
|
|
||||||
imagePanel.setImage (image.getImage ());
|
imagePanel.setImage (image.getImage ());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -264,9 +271,10 @@ public class DataPanel extends JTabbedPane
|
|||||||
AbstractFile.setDebug (value);
|
AbstractFile.setDebug (value);
|
||||||
setText (formattedText, currentDataSource.getText ());
|
setText (formattedText, currentDataSource.getText ());
|
||||||
|
|
||||||
if (currentDataSource instanceof HiResImage
|
if (currentDataSource instanceof HiResImage //
|
||||||
|
|| currentDataSource instanceof MazeLevel // Wizardry
|
||||||
|| currentDataSource instanceof QuickDrawFont)
|
|| currentDataSource instanceof QuickDrawFont)
|
||||||
setDataSource (currentDataSource); // toggles text/image
|
setDataSource (currentDataSource); // toggles text/image
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -298,6 +306,7 @@ public class DataPanel extends JTabbedPane
|
|||||||
JScrollPane outputScrollPane =
|
JScrollPane outputScrollPane =
|
||||||
new JScrollPane (outputPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
|
new JScrollPane (outputPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
|
|
||||||
outputScrollPane.setBorder (null); // remove the ugly default border
|
outputScrollPane.setBorder (null); // remove the ugly default border
|
||||||
add (outputScrollPane, tabName);
|
add (outputScrollPane, tabName);
|
||||||
return outputScrollPane;
|
return outputScrollPane;
|
||||||
@ -355,15 +364,15 @@ public class DataPanel extends JTabbedPane
|
|||||||
removeImage ();
|
removeImage ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dataSource instanceof HiResImage)
|
if (dataSource instanceof HiResImage hri)
|
||||||
{
|
{
|
||||||
((HiResImage) dataSource).checkPalette ();
|
hri.checkPalette ();
|
||||||
image = dataSource.getImage ();
|
image = dataSource.getImage ();
|
||||||
if (((HiResImage) dataSource).isAnimation ())
|
if (((HiResImage) dataSource).isAnimation ())
|
||||||
{
|
{
|
||||||
if (animation != null)
|
if (animation != null)
|
||||||
animation.cancel ();
|
animation.cancel ();
|
||||||
animation = new Worker ((SHRPictureFile2) dataSource);
|
animation = new AnimationWorker (this, (SHRPictureFile2) dataSource);
|
||||||
animation.execute ();
|
animation.execute ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,71 +420,6 @@ public class DataPanel extends JTabbedPane
|
|||||||
textArea.setCaretPosition (0);
|
textArea.setCaretPosition (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
private class ImagePanel extends JPanel
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
private BufferedImage image;
|
|
||||||
private double scale = 1;
|
|
||||||
private double userScale = .5;
|
|
||||||
|
|
||||||
public ImagePanel ()
|
|
||||||
{
|
|
||||||
this.setBackground (new Color (BACKGROUND, BACKGROUND, BACKGROUND));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setScale (double scale)
|
|
||||||
{
|
|
||||||
this.userScale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setImage (BufferedImage image)
|
|
||||||
{
|
|
||||||
this.image = image;
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
if (image != null)
|
|
||||||
{
|
|
||||||
Graphics2D g2 = image.createGraphics ();
|
|
||||||
g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
|
|
||||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
width = image.getWidth ();
|
|
||||||
height = image.getHeight ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
width = height = 0;
|
|
||||||
|
|
||||||
if (true)
|
|
||||||
{
|
|
||||||
if (width < 400 && width > 0)
|
|
||||||
scale = (400 - 1) / width + 1;
|
|
||||||
else
|
|
||||||
scale = 1;
|
|
||||||
if (scale > 4)
|
|
||||||
scale = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
scale *= userScale;
|
|
||||||
|
|
||||||
setPreferredSize (new Dimension ((int) (width * scale), (int) (height * scale)));
|
|
||||||
repaint ();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent (Graphics g)
|
|
||||||
{
|
|
||||||
super.paintComponent (g);
|
|
||||||
|
|
||||||
if (image != null)
|
|
||||||
{
|
|
||||||
Graphics2D g2 = ((Graphics2D) g);
|
|
||||||
g2.transform (AffineTransform.getScaleInstance (scale, scale));
|
|
||||||
g2.drawImage (image,
|
|
||||||
(int) ((getWidth () - image.getWidth () * scale) / 2 / scale), 4, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public void diskSelected (DiskSelectedEvent event)
|
public void diskSelected (DiskSelectedEvent event)
|
||||||
@ -483,6 +427,7 @@ public class DataPanel extends JTabbedPane
|
|||||||
{
|
{
|
||||||
setSelectedIndex (0);
|
setSelectedIndex (0);
|
||||||
setDataSource (null);
|
setDataSource (null);
|
||||||
|
|
||||||
if (event.getFormattedDisk () != null)
|
if (event.getFormattedDisk () != null)
|
||||||
setDataSource (event.getFormattedDisk ().getCatalog ().getDataSource ());
|
setDataSource (event.getFormattedDisk ().getCatalog ().getDataSource ());
|
||||||
else
|
else
|
||||||
@ -524,7 +469,6 @@ public class DataPanel extends JTabbedPane
|
|||||||
{
|
{
|
||||||
setSelectedIndex (0);
|
setSelectedIndex (0);
|
||||||
setDataSource (event.getFileNode ());
|
setDataSource (event.getFileNode ());
|
||||||
// FileNode node = event.getFileNode ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -549,8 +493,7 @@ public class DataPanel extends JTabbedPane
|
|||||||
public void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
|
public void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (currentDataSource instanceof AssemblerProgram
|
if (currentDataSource instanceof AssemblerProgram || currentDataSource instanceof BootSector)
|
||||||
|| currentDataSource instanceof BootSector)
|
|
||||||
setDataSource (currentDataSource);
|
setDataSource (currentDataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,49 +505,4 @@ public class DataPanel extends JTabbedPane
|
|||||||
if (currentDataSource instanceof BasicTextFile)
|
if (currentDataSource instanceof BasicTextFile)
|
||||||
setDataSource (currentDataSource);
|
setDataSource (currentDataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
class Worker extends SwingWorker<Void, Integer>
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
volatile boolean running;
|
|
||||||
SHRPictureFile2 image;
|
|
||||||
|
|
||||||
public Worker (SHRPictureFile2 image)
|
|
||||||
{
|
|
||||||
assert image.isAnimation ();
|
|
||||||
this.image = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancel ()
|
|
||||||
{
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground () throws Exception
|
|
||||||
{
|
|
||||||
running = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (running)
|
|
||||||
{
|
|
||||||
Thread.sleep (image.getDelay ());
|
|
||||||
publish (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InterruptedException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace ();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void process (List<Integer> chunks)
|
|
||||||
{
|
|
||||||
image.nextFrame ();
|
|
||||||
update ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -12,10 +12,10 @@ class PaletteAction extends AbstractAction
|
|||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final Palette palette;
|
private final Palette palette;
|
||||||
private final DataPanel owner;
|
private final OutputPanel owner;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
PaletteAction (DataPanel owner, Palette palette)
|
PaletteAction (OutputPanel owner, Palette palette)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super (palette.getName ());
|
super (palette.getName ());
|
||||||
|
@ -17,11 +17,11 @@ import com.bytezone.diskbrowser.applefile.PaletteFactory.CycleDirection;
|
|||||||
class PreviousPaletteAction extends AbstractAction
|
class PreviousPaletteAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final DataPanel owner;
|
private final OutputPanel owner;
|
||||||
private final ButtonGroup buttonGroup;
|
private final ButtonGroup buttonGroup;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
PreviousPaletteAction (DataPanel owner, ButtonGroup buttonGroup)
|
PreviousPaletteAction (OutputPanel owner, ButtonGroup buttonGroup)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Previous Palette");
|
super ("Previous Palette");
|
||||||
|
@ -16,10 +16,10 @@ import com.bytezone.diskbrowser.utilities.DefaultAction;
|
|||||||
class PrintAction extends DefaultAction
|
class PrintAction extends DefaultAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
DataPanel owner;
|
OutputPanel owner;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public PrintAction (DataPanel owner)
|
public PrintAction (OutputPanel owner)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Print...", "Print the contents of the output panel",
|
super ("Print...", "Print the contents of the output panel",
|
||||||
|
@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
@ -18,7 +16,7 @@ class RootDirectoryAction extends DefaultAction implements QuitListener
|
|||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final String prefsRootDirectory = "Root directory";
|
private static final String prefsRootDirectory = "Root directory";
|
||||||
private final List<RootDirectoryChangeListener> listeners = new ArrayList<> ();
|
|
||||||
private File rootFolder;
|
private File rootFolder;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -27,6 +25,7 @@ class RootDirectoryAction extends DefaultAction implements QuitListener
|
|||||||
{
|
{
|
||||||
super ("Set HOME folder...", "Defines root folder where the disk images are kept",
|
super ("Set HOME folder...", "Defines root folder where the disk images are kept",
|
||||||
"/com/bytezone/diskbrowser/icons/");
|
"/com/bytezone/diskbrowser/icons/");
|
||||||
|
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt H"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt H"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_H);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_H);
|
||||||
|
|
||||||
@ -56,14 +55,6 @@ class RootDirectoryAction extends DefaultAction implements QuitListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
public void addListener (RootDirectoryChangeListener listener)
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
if (!listeners.contains (listener))
|
|
||||||
listeners.add (listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public void quit (Preferences prefs)
|
public void quit (Preferences prefs)
|
||||||
@ -78,9 +69,7 @@ class RootDirectoryAction extends DefaultAction implements QuitListener
|
|||||||
public void restore (Preferences prefs)
|
public void restore (Preferences prefs)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
String rootDirectory = prefs.get (prefsRootDirectory, "");
|
File rootDirectoryFile = new File (prefs.get (prefsRootDirectory, ""));
|
||||||
|
|
||||||
File rootDirectoryFile = new File (rootDirectory);
|
|
||||||
|
|
||||||
if (!rootDirectoryFile.exists () || !rootDirectoryFile.isDirectory ())
|
if (!rootDirectoryFile.exists () || !rootDirectoryFile.isDirectory ())
|
||||||
{
|
{
|
||||||
@ -96,7 +85,7 @@ class RootDirectoryAction extends DefaultAction implements QuitListener
|
|||||||
{
|
{
|
||||||
File oldRootFolder = rootFolder;
|
File oldRootFolder = rootFolder;
|
||||||
rootFolder = newRootFolder;
|
rootFolder = newRootFolder;
|
||||||
for (RootDirectoryChangeListener listener : listeners)
|
|
||||||
listener.rootDirectoryChanged (oldRootFolder, newRootFolder);
|
firePropertyChange ("RootDirectory", oldRootFolder, newRootFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +0,0 @@
|
|||||||
package com.bytezone.diskbrowser.gui;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
|
||||||
public interface RootDirectoryChangeListener
|
|
||||||
// -----------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder);
|
|
||||||
}
|
|
@ -2,25 +2,25 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
|
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.disk.AppleDisk;
|
||||||
|
import com.bytezone.diskbrowser.disk.Disk;
|
||||||
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class SaveDiskAction extends AbstractSaveAction implements DiskSelectionListener
|
class SaveDiskAction extends AbstractSaveAction implements DiskSelectionListener
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
FormattedDisk disk;
|
FormattedDisk formattedDisk;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
SaveDiskAction ()
|
SaveDiskAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Save converted disk...", "Save converted disk");
|
super ("Save converted disk...", "Save converted disk", "Save converted disk");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -28,35 +28,25 @@ class SaveDiskAction extends AbstractSaveAction implements DiskSelectionListener
|
|||||||
public void actionPerformed (ActionEvent evt)
|
public void actionPerformed (ActionEvent evt)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (disk == null)
|
if (formattedDisk == null)
|
||||||
{
|
{
|
||||||
JOptionPane.showMessageDialog (null, "No disk selected");
|
JOptionPane.showMessageDialog (null, "No disk selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileChooser == null)
|
Disk disk = formattedDisk.getDisk ();
|
||||||
|
if (disk instanceof AppleDisk appleDisk)
|
||||||
{
|
{
|
||||||
fileChooser = new JFileChooser ();
|
int blocks = disk.getTotalBlocks ();
|
||||||
fileChooser.setDialogTitle ("Save converted disk");
|
String suffix = blocks <= 560 ? ".dsk" : ".hdv";
|
||||||
}
|
|
||||||
|
|
||||||
fileChooser.setSelectedFile (new File (disk.getName () + ".dsk"));
|
setSelectedFile (new File (formattedDisk.getName () + suffix));
|
||||||
|
|
||||||
if (fileChooser.showSaveDialog (null) == JFileChooser.APPROVE_OPTION)
|
if (fileChooser.showSaveDialog (null) == JFileChooser.APPROVE_OPTION)
|
||||||
{
|
saveBuffer (appleDisk.getBuffer ());
|
||||||
File file = fileChooser.getSelectedFile ();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Files.copy (disk.getDisk ().getFile ().toPath (), file.toPath ());
|
|
||||||
JOptionPane.showMessageDialog (null,
|
|
||||||
String.format ("File %s saved", file.getName ()));
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace ();
|
|
||||||
JOptionPane.showMessageDialog (null, "Disk failed to save");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
System.out.println ("Not an AppleDisk"); // impossible
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -64,7 +54,7 @@ class SaveDiskAction extends AbstractSaveAction implements DiskSelectionListener
|
|||||||
public void diskSelected (DiskSelectedEvent event)
|
public void diskSelected (DiskSelectedEvent event)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.disk = event.getFormattedDisk ();
|
formattedDisk = event.getFormattedDisk ();
|
||||||
setEnabled (disk != null && disk.isTempDisk ());
|
setEnabled (formattedDisk != null && formattedDisk.isTempDisk ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package com.bytezone.diskbrowser.gui;
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
|
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
||||||
|
|
||||||
@ -16,12 +18,17 @@ class SaveFileAction extends AbstractSaveAction implements FileSelectionListener
|
|||||||
//-----------------------------------------------------------------------------------//
|
//-----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
AppleFileSource appleFileSource;
|
AppleFileSource appleFileSource;
|
||||||
|
private JCheckBox formatted = new JCheckBox ("Formatted");
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
SaveFileAction ()
|
SaveFileAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Save file...", "Save currently selected file");
|
super ("Save file...", "Save currently selected file", "Save File");
|
||||||
|
|
||||||
|
fileChooser.setAccessory (formatted);
|
||||||
|
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
|
||||||
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_S, mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -35,30 +42,18 @@ class SaveFileAction extends AbstractSaveAction implements FileSelectionListener
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileChooser == null)
|
if (formatted.isSelected ())
|
||||||
{
|
setSelectedFile (new File (appleFileSource.getUniqueName () + ".txt"));
|
||||||
fileChooser = new JFileChooser ();
|
else
|
||||||
fileChooser.setDialogTitle ("Save File");
|
setSelectedFile (new File (appleFileSource.getUniqueName () + ".bin"));
|
||||||
}
|
|
||||||
|
|
||||||
fileChooser.setSelectedFile (new File (appleFileSource.getUniqueName () + ".bin"));
|
if (fileChooser.showSaveDialog (null) != JFileChooser.APPROVE_OPTION)
|
||||||
|
return;
|
||||||
|
|
||||||
if (fileChooser.showSaveDialog (null) == JFileChooser.APPROVE_OPTION)
|
if (formatted.isSelected ())
|
||||||
{
|
saveBuffer (appleFileSource.getDataSource ().getText ().getBytes ());
|
||||||
File file = fileChooser.getSelectedFile ();
|
else
|
||||||
try
|
saveBuffer (appleFileSource.getDataSource ().getBuffer ());
|
||||||
{
|
|
||||||
Files.write (file.toPath (), appleFileSource.getDataSource ().getBuffer (),
|
|
||||||
StandardOpenOption.CREATE_NEW);
|
|
||||||
JOptionPane.showMessageDialog (null,
|
|
||||||
String.format ("File %s saved", file.getName ()));
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace ();
|
|
||||||
JOptionPane.showMessageDialog (null, "File failed to save");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -67,8 +62,8 @@ class SaveFileAction extends AbstractSaveAction implements FileSelectionListener
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.appleFileSource = event.appleFileSource;
|
this.appleFileSource = event.appleFileSource;
|
||||||
setEnabled (
|
|
||||||
event.appleFileSource != null && event.appleFileSource.getDataSource () != null
|
setEnabled (appleFileSource != null && appleFileSource.getDataSource () != null
|
||||||
&& event.appleFileSource.getDataSource ().getBuffer () != null);
|
&& appleFileSource.getDataSource ().getBuffer () != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,14 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.util.List;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
|
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.disk.Disk;
|
||||||
|
import com.bytezone.diskbrowser.disk.DiskAddress;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class SaveSectorsAction extends AbstractSaveAction implements SectorSelectionListener
|
class SaveSectorsAction extends AbstractSaveAction implements SectorSelectionListener
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
@ -19,7 +20,7 @@ class SaveSectorsAction extends AbstractSaveAction implements SectorSelectionLis
|
|||||||
SaveSectorsAction ()
|
SaveSectorsAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Save sectors...", "Save currently selected sectors");
|
super ("Save sectors...", "Save currently selected sectors", "Save sectors");
|
||||||
this.setEnabled (false);
|
this.setEnabled (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,31 +35,16 @@ class SaveSectorsAction extends AbstractSaveAction implements SectorSelectionLis
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileChooser == null)
|
// block 0 will not read when it is the only DiskAddress in the list
|
||||||
{
|
List<DiskAddress> blocks = event.getSectors ();
|
||||||
fileChooser = new JFileChooser ();
|
Disk disk = event.getFormattedDisk ().getDisk ();
|
||||||
fileChooser.setDialogTitle ("Save sectors");
|
byte[] buffer =
|
||||||
}
|
blocks.size () == 1 ? disk.readBlock (blocks.get (0)) : disk.readBlocks (blocks);
|
||||||
|
|
||||||
fileChooser.setSelectedFile (new File ("savedSectors.bin"));
|
setSelectedFile (new File ("SavedSectors.bin"));
|
||||||
|
|
||||||
if (fileChooser.showSaveDialog (null) == JFileChooser.APPROVE_OPTION)
|
if (fileChooser.showSaveDialog (null) == JFileChooser.APPROVE_OPTION)
|
||||||
{
|
saveBuffer (buffer);
|
||||||
File file = fileChooser.getSelectedFile ();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] buffer =
|
|
||||||
event.getFormattedDisk ().getDisk ().readBlocks (event.getSectors ());
|
|
||||||
Files.write (file.toPath (), buffer, StandardOpenOption.CREATE_NEW);
|
|
||||||
JOptionPane.showMessageDialog (null,
|
|
||||||
String.format ("File %s saved", file.getName ()));
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace ();
|
|
||||||
JOptionPane.showMessageDialog (null, "File failed to save");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -10,11 +10,11 @@ import javax.swing.KeyStroke;
|
|||||||
|
|
||||||
public class ScaleAction extends AbstractAction
|
public class ScaleAction extends AbstractAction
|
||||||
{
|
{
|
||||||
private final DataPanel owner;
|
private final OutputPanel owner;
|
||||||
private double scale;
|
private double scale;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public ScaleAction (DataPanel owner, double scale, int menu)
|
public ScaleAction (OutputPanel owner, double scale, int menu)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Scale " + scale);
|
super ("Scale " + scale);
|
||||||
|
@ -29,14 +29,14 @@ class ScrollRuler extends JComponent
|
|||||||
private boolean isHex = true;
|
private boolean isHex = true;
|
||||||
private boolean isTrackMode = true;
|
private boolean isTrackMode = true;
|
||||||
private LayoutDetails layoutDetails;
|
private LayoutDetails layoutDetails;
|
||||||
private final JComponent image;
|
private final DiskLayoutImage diskLayoutImage;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
ScrollRuler (JComponent image, int orientation)
|
ScrollRuler (DiskLayoutImage diskLayoutImage, int orientation)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
this.image = image;
|
this.diskLayoutImage = diskLayoutImage;
|
||||||
|
|
||||||
// set defaults until setLayout is called
|
// set defaults until setLayout is called
|
||||||
if (orientation == HORIZONTAL)
|
if (orientation == HORIZONTAL)
|
||||||
@ -46,20 +46,20 @@ class ScrollRuler extends JComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public void setLayout (LayoutDetails layout)
|
public void setLayout (LayoutDetails layoutDetails)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.layoutDetails = layout;
|
this.layoutDetails = layoutDetails;
|
||||||
|
|
||||||
// Must match the preferred size of DiskLayoutImage
|
// Must match the preferred size of DiskLayoutImage
|
||||||
if (orientation == HORIZONTAL)
|
if (orientation == HORIZONTAL)
|
||||||
setPreferredSize (
|
setPreferredSize (new Dimension (
|
||||||
new Dimension (layout.block.width * layout.grid.width + 1, HEIGHT));
|
layoutDetails.block.width * layoutDetails.grid.width + 1, HEIGHT));
|
||||||
else
|
else
|
||||||
setPreferredSize (
|
setPreferredSize (new Dimension (WIDTH,
|
||||||
new Dimension (WIDTH, layout.block.height * layout.grid.height + 1));
|
layoutDetails.block.height * layoutDetails.grid.height + 1));
|
||||||
|
|
||||||
setTrackMode (layout.grid.width == 16 || layout.grid.width == 13);
|
setTrackMode (layoutDetails.grid.width == 16 || layoutDetails.grid.width == 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -105,7 +105,7 @@ class ScrollRuler extends JComponent
|
|||||||
{
|
{
|
||||||
int start = (clipRect.x / width);
|
int start = (clipRect.x / width);
|
||||||
int end = start + clipRect.width / width;
|
int end = start + clipRect.width / width;
|
||||||
end = Math.min (end, image.getWidth () / width - 1);
|
end = Math.min (end, diskLayoutImage.getWidth () / width - 1);
|
||||||
|
|
||||||
String format;
|
String format;
|
||||||
int offset;
|
int offset;
|
||||||
@ -131,7 +131,7 @@ class ScrollRuler extends JComponent
|
|||||||
{
|
{
|
||||||
int start = (clipRect.y / height);
|
int start = (clipRect.y / height);
|
||||||
int end = start + clipRect.height / height;
|
int end = start + clipRect.height / height;
|
||||||
end = Math.min (end, image.getHeight () / height - 1);
|
end = Math.min (end, diskLayoutImage.getHeight () / height - 1);
|
||||||
|
|
||||||
String format = isHex ? "%04X" : "%04d";
|
String format = isHex ? "%04X" : "%04d";
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ class SectorSelectedEvent extends EventObject
|
|||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final List<DiskAddress> sectors;
|
private final List<DiskAddress> sectors;
|
||||||
private final FormattedDisk owner;
|
private final FormattedDisk owner; // for dual-format disks
|
||||||
boolean redo;
|
boolean redo;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -20,6 +20,7 @@ class SectorSelectedEvent extends EventObject
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super (source);
|
super (source);
|
||||||
|
|
||||||
this.sectors = sectors;
|
this.sectors = sectors;
|
||||||
// always store the parent if this disk is part of a dual-dos disk
|
// always store the parent if this disk is part of a dual-dos disk
|
||||||
this.owner = owner.getParent () == null ? owner : owner.getParent ();
|
this.owner = owner.getParent () == null ? owner : owner.getParent ();
|
||||||
@ -44,8 +45,10 @@ class SectorSelectedEvent extends EventObject
|
|||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
SectorListConverter slc = new SectorListConverter (sectors);
|
|
||||||
text.append (slc.sectorText);
|
SectorListConverter sectorListConverter = new SectorListConverter (sectors);
|
||||||
|
text.append (sectorListConverter.sectorText);
|
||||||
|
|
||||||
return text.toString ();
|
return text.toString ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,26 +5,23 @@ import java.awt.event.KeyEvent;
|
|||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class ShowFreeSectorsAction extends AbstractAction
|
class ShowFreeSectorsAction extends AbstractAction
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
DiskLayoutPanel panel;
|
|
||||||
MenuHandler mh;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
ShowFreeSectorsAction (MenuHandler mh, DiskLayoutPanel panel)
|
ShowFreeSectorsAction ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super ("Show free sectors");
|
super ("Show free sectors");
|
||||||
|
|
||||||
putValue (Action.SHORT_DESCRIPTION,
|
putValue (Action.SHORT_DESCRIPTION,
|
||||||
"Display which sectors are marked free in the disk layout panel");
|
"Display which sectors are marked free in the disk layout panel");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt F"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt F"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_F);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_F);
|
||||||
this.panel = panel;
|
|
||||||
this.mh = mh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -32,6 +29,7 @@ class ShowFreeSectorsAction extends AbstractAction
|
|||||||
public void actionPerformed (ActionEvent e)
|
public void actionPerformed (ActionEvent e)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
panel.setFree (mh.showFreeSectorsItem.isSelected ());
|
firePropertyChange (e.getActionCommand (), null,
|
||||||
|
((JMenuItem) e.getSource ()).isSelected ());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ import com.bytezone.diskbrowser.utilities.Utility;
|
|||||||
class TreeBuilder
|
class TreeBuilder
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static SimpleDateFormat sdf = new SimpleDateFormat ("dd MMM yyyy");
|
private static SimpleDateFormat sdf = new SimpleDateFormat ("dd LLL yyyy");
|
||||||
|
|
||||||
private final FileComparator fileComparator = new FileComparator ();
|
private final FileComparator fileComparator = new FileComparator ();
|
||||||
private final JTree tree;
|
private final JTree tree;
|
||||||
@ -219,8 +219,7 @@ class TreeBuilder
|
|||||||
String type = pos > 0 && !f.isDirectory () ? name.substring (pos) : "";
|
String type = pos > 0 && !f.isDirectory () ? name.substring (pos) : "";
|
||||||
String size = f.isDirectory () ? "" : String.format ("%,14d", f.length ());
|
String size = f.isDirectory () ? "" : String.format ("%,14d", f.length ());
|
||||||
text.append (String.format ("%s %-40.40s %s %-14s %s%n",
|
text.append (String.format ("%s %-40.40s %s %-14s %s%n",
|
||||||
f.isDirectory () ? "D" : " ", name, sdf.format (d).replace (".", ""), size,
|
f.isDirectory () ? "D" : " ", name, sdf.format (d), size, type));
|
||||||
type));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class ZObject extends AbstractFile implements Comparable<ZObject>
|
|||||||
propertyTablePtr = header.getWord (offset + 7);
|
propertyTablePtr = header.getWord (offset + 7);
|
||||||
int ptr = propertyTablePtr;
|
int ptr = propertyTablePtr;
|
||||||
int nameLength = header.getByte (ptr) * 2;
|
int nameLength = header.getByte (ptr) * 2;
|
||||||
this.name = nameLength == 0 ? "<<" + id + ">>" : new ZString (header, ++ptr).value;
|
setName (nameLength == 0 ? "<<" + id + ">>" : new ZString (header, ++ptr).value);
|
||||||
ptr += nameLength;
|
ptr += nameLength;
|
||||||
|
|
||||||
// read each property
|
// read each property
|
||||||
@ -84,11 +84,11 @@ class ZObject extends AbstractFile implements Comparable<ZObject>
|
|||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
text.append (String.format ("ID : %02X (%<3d) %s%n%n", id, name));
|
text.append (String.format ("ID : %02X (%<3d) %s%n%n", id, getName ()));
|
||||||
|
|
||||||
String obj1 = parent == 0 ? "" : header.getObject (parent - 1).name;
|
String obj1 = parent == 0 ? "" : header.getObject (parent - 1).getName ();
|
||||||
String obj2 = sibling == 0 ? "" : header.getObject (sibling - 1).name;
|
String obj2 = sibling == 0 ? "" : header.getObject (sibling - 1).getName ();
|
||||||
String obj3 = child == 0 ? "" : header.getObject (child - 1).name;
|
String obj3 = child == 0 ? "" : header.getObject (child - 1).getName ();
|
||||||
|
|
||||||
text.append (String.format ("Parent : %02X (%<3d) %s%n", parent, obj1));
|
text.append (String.format ("Parent : %02X (%<3d) %s%n", parent, obj1));
|
||||||
text.append (String.format ("Sibling : %02X (%<3d) %s%n", sibling, obj2));
|
text.append (String.format ("Sibling : %02X (%<3d) %s%n", sibling, obj2));
|
||||||
@ -132,7 +132,7 @@ class ZObject extends AbstractFile implements Comparable<ZObject>
|
|||||||
public String toString ()
|
public String toString ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return HexFormatter.getHexString (buffer, startPtr, HEADER_SIZE) + " " + name;
|
return HexFormatter.getHexString (buffer, startPtr, HEADER_SIZE) + " " + getName ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -200,7 +200,7 @@ class ZObject extends AbstractFile implements Comparable<ZObject>
|
|||||||
if (propertyNumber >= 19) // directions
|
if (propertyNumber >= 19) // directions
|
||||||
{
|
{
|
||||||
ZObject object = getObject ();
|
ZObject object = getObject ();
|
||||||
String objectName = object == null ? "no object" : object.name;
|
String objectName = object == null ? "no object" : object.getName ();
|
||||||
|
|
||||||
switch (length)
|
switch (length)
|
||||||
{
|
{
|
||||||
@ -271,8 +271,8 @@ class ZObject extends AbstractFile implements Comparable<ZObject>
|
|||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
int objectId = header.getByte (ptr + i + 1);
|
int objectId = header.getByte (ptr + i + 1);
|
||||||
text.append (
|
text.append (String.format ("%s%s", (i == 0 ? "" : ", "),
|
||||||
String.format ("%s%s", (i == 0 ? "" : ", "), getObject (objectId).name));
|
getObject (objectId).getName ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
@ -296,6 +296,6 @@ class ZObject extends AbstractFile implements Comparable<ZObject>
|
|||||||
public int compareTo (ZObject o)
|
public int compareTo (ZObject o)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return this.name.compareTo (o.name);
|
return this.getName ().compareTo (o.getName ());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,10 +15,8 @@ import com.bytezone.diskbrowser.utilities.Utility;
|
|||||||
public class WozFile
|
public class WozFile
|
||||||
//-----------------------------------------------------------------------------------//
|
//-----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final byte[] address16prologue =
|
private static final byte[] address16prologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0x96 };
|
||||||
{ (byte) 0xD5, (byte) 0xAA, (byte) 0x96 };
|
private static final byte[] address13prologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xB5 };
|
||||||
private static final byte[] address13prologue =
|
|
||||||
{ (byte) 0xD5, (byte) 0xAA, (byte) 0xB5 };
|
|
||||||
private static final byte[] dataPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xAD };
|
private static final byte[] dataPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xAD };
|
||||||
private static final byte[] epilogue = { (byte) 0xDE, (byte) 0xAA, (byte) 0xEB };
|
private static final byte[] epilogue = { (byte) 0xDE, (byte) 0xAA, (byte) 0xEB };
|
||||||
// apparently it can be DE AA Ex
|
// apparently it can be DE AA Ex
|
||||||
@ -29,9 +27,9 @@ public class WozFile
|
|||||||
private static final int TRK_SIZE = 0x1A00;
|
private static final int TRK_SIZE = 0x1A00;
|
||||||
private static final int DATA_SIZE = TRK_SIZE - 10;
|
private static final int DATA_SIZE = TRK_SIZE - 10;
|
||||||
|
|
||||||
private static int[][] interleave =
|
private static int[][] interleave = //
|
||||||
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, // 13 sector
|
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, // 13 sector
|
||||||
{ 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 } }; // 16 sector
|
{ 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 } }; // 16 sector
|
||||||
|
|
||||||
public final File file;
|
public final File file;
|
||||||
|
|
||||||
@ -146,8 +144,7 @@ public class WozFile
|
|||||||
{
|
{
|
||||||
if (info != null)
|
if (info != null)
|
||||||
System.out.println (info);
|
System.out.println (info);
|
||||||
throw new DiskNibbleException (
|
throw new DiskNibbleException (String.format ("Invalid chunk name character: %02X%n", val));
|
||||||
String.format ("Invalid chunk name character: %02X%n", val));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,9 +299,9 @@ public class WozFile
|
|||||||
String wozBase2 = home + "Dropbox/Examples/woz test images/WOZ 2.0/";
|
String wozBase2 = home + "Dropbox/Examples/woz test images/WOZ 2.0/";
|
||||||
String wozBase3 = home + "Dropbox/Examples/woz test images/WOZ 2.0/3.5/";
|
String wozBase3 = home + "Dropbox/Examples/woz test images/WOZ 2.0/3.5/";
|
||||||
File[] files = { new File (home + "code/python/wozardry-2.0/bill.woz"),
|
File[] files = { new File (home + "code/python/wozardry-2.0/bill.woz"),
|
||||||
new File (wozBase2 + "DOS 3.3 System Master.woz"),
|
new File (wozBase2 + "DOS 3.3 System Master.woz"),
|
||||||
new File (wozBase1 + "DOS 3.3 System Master.woz"),
|
new File (wozBase1 + "DOS 3.3 System Master.woz"),
|
||||||
new File (wozBase3 + "Apple IIgs System Disk 1.1.woz") };
|
new File (wozBase3 + "Apple IIgs System Disk 1.1.woz") };
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new WozFile (files[3]);
|
new WozFile (files[3]);
|
||||||
@ -369,8 +366,7 @@ public class WozFile
|
|||||||
String diskTypeText = diskType == 1 ? "5.25" : "3.5";
|
String diskTypeText = diskType == 1 ? "5.25" : "3.5";
|
||||||
|
|
||||||
text.append (String.format ("Version ............. %d%n", wozVersion));
|
text.append (String.format ("Version ............. %d%n", wozVersion));
|
||||||
text.append (
|
text.append (String.format ("Disk type ........... %d (%s\")%n", diskType, diskTypeText));
|
||||||
String.format ("Disk type ........... %d (%s\")%n", diskType, diskTypeText));
|
|
||||||
text.append (String.format ("Write protected ..... %d%n", writeProtected));
|
text.append (String.format ("Write protected ..... %d%n", writeProtected));
|
||||||
text.append (String.format ("Synchronized ........ %d%n", synchronised));
|
text.append (String.format ("Synchronized ........ %d%n", synchronised));
|
||||||
text.append (String.format ("Cleaned ............. %d%n", cleaned));
|
text.append (String.format ("Cleaned ............. %d%n", cleaned));
|
||||||
@ -378,9 +374,8 @@ public class WozFile
|
|||||||
|
|
||||||
if (wozVersion > 1)
|
if (wozVersion > 1)
|
||||||
{
|
{
|
||||||
String bootSectorFormatText =
|
String bootSectorFormatText = bootSectorFormat == 0 ? "Unknown"
|
||||||
bootSectorFormat == 0 ? "Unknown" : bootSectorFormat == 1 ? "16 sector"
|
: bootSectorFormat == 1 ? "16 sector" : bootSectorFormat == 2 ? "13 sector" : "Hybrid";
|
||||||
: bootSectorFormat == 2 ? "13 sector" : "Hybrid";
|
|
||||||
|
|
||||||
text.append (String.format ("%nSides ............... %d%n", sides));
|
text.append (String.format ("%nSides ............... %d%n", sides));
|
||||||
text.append (String.format ("Boot sector format .. %d (%s)%n", bootSectorFormat,
|
text.append (String.format ("Boot sector format .. %d (%s)%n", bootSectorFormat,
|
||||||
@ -468,8 +463,7 @@ public class WozFile
|
|||||||
bitCount = val16 (rawBuffer, ptr + DATA_SIZE + 2);
|
bitCount = val16 (rawBuffer, ptr + DATA_SIZE + 2);
|
||||||
|
|
||||||
if (debug1)
|
if (debug1)
|
||||||
System.out.println (
|
System.out.println ((String.format ("Bytes: %2d, Bits: %,8d%n%n", bytesUsed, bitCount)));
|
||||||
(String.format ("Bytes: %2d, Bits: %,8d%n%n", bytesUsed, bitCount)));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -612,10 +606,8 @@ public class WozFile
|
|||||||
for (Sector sector : sectors)
|
for (Sector sector : sectors)
|
||||||
if (sector.dataOffset > 0)
|
if (sector.dataOffset > 0)
|
||||||
{
|
{
|
||||||
byte[] decodedBuffer =
|
byte[] decodedBuffer = diskReader.decodeSector (newBuffer, sector.dataOffset + 3);
|
||||||
diskReader.decodeSector (newBuffer, sector.dataOffset + 3);
|
int ptr = SECTOR_SIZE * (sector.trackNo * diskSectors + interleave[ndx][sector.sectorNo]);
|
||||||
int ptr = SECTOR_SIZE
|
|
||||||
* (sector.trackNo * diskSectors + interleave[ndx][sector.sectorNo]);
|
|
||||||
System.arraycopy (decodedBuffer, 0, diskBuffer, ptr, decodedBuffer.length);
|
System.arraycopy (decodedBuffer, 0, diskBuffer, ptr, decodedBuffer.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -627,8 +619,7 @@ public class WozFile
|
|||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
if (info.wozVersion == 1)
|
if (info.wozVersion == 1)
|
||||||
text.append (
|
text.append (String.format ("WOZ1: Bytes: %2d, Bits: %,8d%n%n", bytesUsed, bitCount));
|
||||||
String.format ("WOZ1: Bytes: %2d, Bits: %,8d%n%n", bytesUsed, bitCount));
|
|
||||||
else
|
else
|
||||||
text.append (String.format ("WOZ2: Start: %4d, Blocks: %2d, Bits: %,8d%n%n",
|
text.append (String.format ("WOZ2: Start: %4d, Blocks: %2d, Bits: %,8d%n%n",
|
||||||
startingBlock, blockCount, bitCount));
|
startingBlock, blockCount, bitCount));
|
||||||
@ -728,9 +719,8 @@ public class WozFile
|
|||||||
String fld = info.diskType == 1 ? "Vol" : info.diskType == 2 ? "Sde" : "???";
|
String fld = info.diskType == 1 ? "Vol" : info.diskType == 2 ? "Sde" : "???";
|
||||||
String dataOffsetText = dataOffset < 0 ? "" : String.format ("%04X", dataOffset);
|
String dataOffsetText = dataOffset < 0 ? "" : String.format ("%04X", dataOffset);
|
||||||
|
|
||||||
return String.format (
|
return String.format ("%s: %02X Trk: %02X Sct: %02X Chk: %02X Add: %04X Dat: %s", fld,
|
||||||
"%s: %02X Trk: %02X Sct: %02X Chk: %02X Add: %04X Dat: %s", fld, volume,
|
volume, trackNo, sectorNo, checksum, addressOffset, dataOffsetText);
|
||||||
trackNo, sectorNo, checksum, addressOffset, dataOffsetText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.bytezone.diskbrowser.utilities;
|
package com.bytezone.diskbrowser.nufx;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -10,6 +10,7 @@ import com.bytezone.diskbrowser.prodos.write.DiskFullException;
|
|||||||
import com.bytezone.diskbrowser.prodos.write.FileAlreadyExistsException;
|
import com.bytezone.diskbrowser.prodos.write.FileAlreadyExistsException;
|
||||||
import com.bytezone.diskbrowser.prodos.write.ProdosDisk;
|
import com.bytezone.diskbrowser.prodos.write.ProdosDisk;
|
||||||
import com.bytezone.diskbrowser.prodos.write.VolumeCatalogFullException;
|
import com.bytezone.diskbrowser.prodos.write.VolumeCatalogFullException;
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class Binary2
|
public class Binary2
|
||||||
@ -19,11 +20,11 @@ public class Binary2
|
|||||||
"------------------------------------------------------"
|
"------------------------------------------------------"
|
||||||
+ "-----------------------";
|
+ "-----------------------";
|
||||||
|
|
||||||
Binary2Header binary2Header;
|
private Binary2Header binary2Header;
|
||||||
byte[] buffer;
|
private byte[] buffer;
|
||||||
List<Binary2Header> headers = new ArrayList<> ();
|
private List<Binary2Header> headers = new ArrayList<> ();
|
||||||
int totalBlocks;
|
private int totalBlocks;
|
||||||
String fileName;
|
private String fileName;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public Binary2 (Path path) throws IOException
|
public Binary2 (Path path) throws IOException
|
||||||
@ -31,18 +32,26 @@ public class Binary2
|
|||||||
{
|
{
|
||||||
fileName = path.toFile ().getName ();
|
fileName = path.toFile ().getName ();
|
||||||
buffer = Files.readAllBytes (path);
|
buffer = Files.readAllBytes (path);
|
||||||
|
read (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private void read (byte[] buffer)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
int ptr = 0;
|
int ptr = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
binary2Header = new Binary2Header (buffer, ptr);
|
binary2Header = new Binary2Header (buffer, ptr);
|
||||||
System.out.println (binary2Header);
|
|
||||||
headers.add (binary2Header);
|
ptr += ((binary2Header.eof - 1) / 128 + 2) * 128;
|
||||||
|
if (ptr > buffer.length) // not enough blocks for this file
|
||||||
|
break;
|
||||||
|
|
||||||
totalBlocks += binary2Header.totalBlocks;
|
totalBlocks += binary2Header.totalBlocks;
|
||||||
ptr += ((binary2Header.eof - 1) / 128 + 1) * 128 + 128;
|
headers.add (binary2Header);
|
||||||
} while (binary2Header.filesToFollow > 0);
|
} while (binary2Header.filesToFollow > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -57,9 +66,19 @@ public class Binary2
|
|||||||
byte[] dataBuffer = new byte[header.eof]; // this sux
|
byte[] dataBuffer = new byte[header.eof]; // this sux
|
||||||
System.arraycopy (buffer, header.ptr + 128, dataBuffer, 0, dataBuffer.length);
|
System.arraycopy (buffer, header.ptr + 128, dataBuffer, 0, dataBuffer.length);
|
||||||
|
|
||||||
disk.addFile (header.fileName, header.fileType, header.auxType, header.created,
|
if (header.compressed && dataBuffer[0] == 0x76 && dataBuffer[1] == (byte) 0xFF)
|
||||||
header.modified, dataBuffer, header.eof);
|
{
|
||||||
|
String name = Utility.getCString (dataBuffer, 4);
|
||||||
|
|
||||||
|
Squeeze squeeze = new Squeeze ();
|
||||||
|
byte[] tmp = squeeze.unSqueeze (dataBuffer);
|
||||||
|
|
||||||
|
disk.addFile (name, header.fileType, header.auxType, header.created,
|
||||||
|
header.modified, tmp, tmp.length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
disk.addFile (header.fileName, header.fileType, header.auxType, header.created,
|
||||||
|
header.modified, dataBuffer, header.eof);
|
||||||
}
|
}
|
||||||
disk.close ();
|
disk.close ();
|
||||||
|
|
||||||
@ -82,24 +101,11 @@ public class Binary2
|
|||||||
|
|
||||||
text.append (String.format ("%s%n", UNDERLINE));
|
text.append (String.format ("%s%n", UNDERLINE));
|
||||||
|
|
||||||
// int totalUncompressedSize = 0;
|
|
||||||
// int totalCompressedSize = 0;
|
|
||||||
|
|
||||||
for (Binary2Header header : headers)
|
for (Binary2Header header : headers)
|
||||||
{
|
|
||||||
text.append (String.format ("%s%n", header.getLine ()));
|
text.append (String.format ("%s%n", header.getLine ()));
|
||||||
// totalUncompressedSize += record.getUncompressedSize ();
|
|
||||||
// totalCompressedSize += record.getCompressedSize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
text.append (String.format ("%s%n", UNDERLINE));
|
text.append (String.format ("%s%n", UNDERLINE));
|
||||||
|
|
||||||
// float pct = 0;
|
|
||||||
// if (totalUncompressedSize > 0)
|
|
||||||
// pct = totalCompressedSize * 100 / totalUncompressedSize;
|
|
||||||
// text.append (String.format (" Uncomp:%7d Comp:%7d %%of orig:%3.0f%%%n%n",
|
|
||||||
// totalUncompressedSize, totalCompressedSize, pct));
|
|
||||||
|
|
||||||
return text.toString ();
|
return text.toString ();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.bytezone.diskbrowser.utilities;
|
package com.bytezone.diskbrowser.nufx;
|
||||||
|
|
||||||
import static com.bytezone.diskbrowser.prodos.ProdosConstants.fileTypes;
|
import static com.bytezone.diskbrowser.prodos.ProdosConstants.fileTypes;
|
||||||
|
|
||||||
@ -6,16 +6,17 @@ import java.time.LocalDateTime;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.prodos.write.ProdosDisk;
|
import com.bytezone.diskbrowser.prodos.write.ProdosDisk;
|
||||||
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class Binary2Header
|
public class Binary2Header
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("dd-LLL-yy HH:mm");
|
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("dd-LLL-yy HH:mm");
|
||||||
static String[] osTypes =
|
static String[] osTypes = { "Prodos", "DOS 3.3", "Reserved", "DOS 3.2 or 3.1", "Pascal",
|
||||||
{ "Prodos", "DOS 3.3", "Reserved", "DOS 3.2 or 3.1", "Pascal", "Macintosh MFS",
|
"Macintosh MFS", "Macintosh HFS", "Lisa", "CPM", "Reserved", "MS-DOS", "High Sierra (CD-ROM)",
|
||||||
"Macintosh HFS", "Lisa", "CPM", "Reserved", "MS-DOS", "High Sierra (CD-ROM)",
|
"ISO 9660 (CD-ROM)", "AppleShare" };
|
||||||
"ISO 9660 (CD-ROM)", "AppleShare" };
|
|
||||||
|
|
||||||
int ptr;
|
int ptr;
|
||||||
byte[] buffer;
|
byte[] buffer;
|
||||||
@ -87,8 +88,8 @@ public class Binary2Header
|
|||||||
public String getLine ()
|
public String getLine ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return String.format (" %-33s %3s $%04X %s unc %7d", fileName,
|
return String.format (" %-33s %3s $%04X %s unc %7d", fileName, fileTypes[fileType],
|
||||||
fileTypes[fileType], auxType, modified.format (formatter), eof);
|
auxType, modified.format (formatter), eof);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -115,12 +116,13 @@ public class Binary2Header
|
|||||||
text.append (String.format ("Prodos storage type ... %02X%n", prodos16storageType));
|
text.append (String.format ("Prodos storage type ... %02X%n", prodos16storageType));
|
||||||
text.append (String.format ("Prodos total blocks ... %02X%n", prodos16totalBlocks));
|
text.append (String.format ("Prodos total blocks ... %02X%n", prodos16totalBlocks));
|
||||||
text.append (String.format ("Prodos eof ............ %06X %<,d%n", prodos16eof));
|
text.append (String.format ("Prodos eof ............ %06X %<,d%n", prodos16eof));
|
||||||
text.append (
|
text.append (String.format ("Disk space needed ..... %08X %<,d%n", diskSpaceRequired));
|
||||||
String.format ("Disk space needed ..... %08X %<,d%n", diskSpaceRequired));
|
text.append (String.format ("OS type ............... %02X %s%n", osType, osTypes[osType]));
|
||||||
text.append (
|
|
||||||
String.format ("OS type ............... %02X %s%n", osType, osTypes[osType]));
|
|
||||||
text.append (String.format ("Native file type ...... %02X%n", nativeFileType));
|
text.append (String.format ("Native file type ...... %02X%n", nativeFileType));
|
||||||
text.append (String.format ("Data flags ............ %02X%n", dataFlags));
|
text.append (String.format ("Data flags ............ %02X%n", dataFlags));
|
||||||
|
text.append (String.format (" compressed .......... %s%n", compressed));
|
||||||
|
text.append (String.format (" encrypted ........... %s%n", encrypted));
|
||||||
|
text.append (String.format (" sparse .............. %s%n", sparsePacked));
|
||||||
text.append (String.format ("Version ............... %02X%n", version));
|
text.append (String.format ("Version ............... %02X%n", version));
|
||||||
text.append (String.format ("Following files ....... %02X%n", filesToFollow));
|
text.append (String.format ("Following files ....... %02X%n", filesToFollow));
|
||||||
|
|
@ -1,9 +1,11 @@
|
|||||||
package com.bytezone.diskbrowser.utilities;
|
package com.bytezone.diskbrowser.nufx;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
abstract class LZW
|
abstract class LZW
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
@ -17,7 +19,7 @@ abstract class LZW
|
|||||||
|
|
||||||
int crc;
|
int crc;
|
||||||
int crcBase;
|
int crcBase;
|
||||||
int v3eof; // LZW/2 calculates the crc sans padding
|
int v3eof; // LZW/2 calculates the crc without padding
|
||||||
|
|
||||||
private int byteBuffer; // one character buffer
|
private int byteBuffer; // one character buffer
|
||||||
private int bitsLeft; // unused bits left in buffer
|
private int bitsLeft; // unused bits left in buffer
|
||||||
@ -88,7 +90,7 @@ abstract class LZW
|
|||||||
}
|
}
|
||||||
|
|
||||||
bitsLeft--;
|
bitsLeft--;
|
||||||
boolean bit = ((byteBuffer << bitsLeft) & 0x80) == 0x80;
|
boolean bit = ((byteBuffer << bitsLeft) & 0x80) != 0;
|
||||||
|
|
||||||
return bit;
|
return bit;
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
package com.bytezone.diskbrowser.utilities;
|
package com.bytezone.diskbrowser.nufx;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class LZW1 extends LZW
|
class LZW1 extends LZW
|
@ -1,4 +1,6 @@
|
|||||||
package com.bytezone.diskbrowser.utilities;
|
package com.bytezone.diskbrowser.nufx;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class LZW2 extends LZW
|
class LZW2 extends LZW
|
161
src/com/bytezone/diskbrowser/nufx/LZW3.java
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package com.bytezone.diskbrowser.nufx;
|
||||||
|
|
||||||
|
// DreamGraphix LZW
|
||||||
|
// code ported from CiderPress' DreamGraphix::UnpackDG()
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
public class LZW3
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
static final int[] bitMasks = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1FF, 0x3FF, 0x7FF, 0xFFF };
|
||||||
|
static final int CLEAR_CODE = 256;
|
||||||
|
static final int EOF_CODE = 257;
|
||||||
|
static final int FIRST_FREE_CODE = 258;
|
||||||
|
|
||||||
|
int nBitMod1;
|
||||||
|
int nBitMask;
|
||||||
|
int finChar;
|
||||||
|
int oldCode;
|
||||||
|
int inCode;
|
||||||
|
int freeCode;
|
||||||
|
int maxCode;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
int bitOffset;
|
||||||
|
|
||||||
|
int[] hashNext = new int[4096];
|
||||||
|
int[] hashChar = new int[4096];
|
||||||
|
|
||||||
|
int ptr = 0;
|
||||||
|
int iCode;
|
||||||
|
int[] stack = new int[32768];
|
||||||
|
int stackIdx = 0;
|
||||||
|
|
||||||
|
byte[] srcBuf;
|
||||||
|
byte[] dstBuf;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public int unpack (byte[] src, byte[] dst, int max)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
assert max <= dst.length;
|
||||||
|
|
||||||
|
srcBuf = src;
|
||||||
|
dstBuf = dst;
|
||||||
|
|
||||||
|
initTable ();
|
||||||
|
|
||||||
|
int a;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
bitOffset = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (ptr > max)
|
||||||
|
{
|
||||||
|
System.out.println ("LZW3 overrun");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iCode = readCode ();
|
||||||
|
|
||||||
|
if (iCode == EOF_CODE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (iCode == CLEAR_CODE)
|
||||||
|
{
|
||||||
|
initTable ();
|
||||||
|
iCode = readCode ();
|
||||||
|
|
||||||
|
oldCode = iCode;
|
||||||
|
k = iCode;
|
||||||
|
finChar = iCode;
|
||||||
|
dstBuf[ptr++] = (byte) iCode;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = inCode = iCode;
|
||||||
|
|
||||||
|
if (iCode >= freeCode)
|
||||||
|
{
|
||||||
|
stack[stackIdx++] = finChar;
|
||||||
|
a = oldCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (a >= 256)
|
||||||
|
{
|
||||||
|
y = a;
|
||||||
|
a = hashChar[y];
|
||||||
|
stack[stackIdx++] = a;
|
||||||
|
a = hashNext[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
finChar = a;
|
||||||
|
k = a;
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
dstBuf[ptr + y++] = (byte) a;
|
||||||
|
|
||||||
|
while (stackIdx > 0)
|
||||||
|
{
|
||||||
|
a = stack[--stackIdx];
|
||||||
|
dstBuf[ptr + y++] = (byte) a;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += y;
|
||||||
|
|
||||||
|
addCode ();
|
||||||
|
|
||||||
|
oldCode = inCode;
|
||||||
|
|
||||||
|
if (freeCode < maxCode)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nBitMod1 == 12)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nBitMod1++;
|
||||||
|
nBitMask = bitMasks[nBitMod1];
|
||||||
|
maxCode <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private void initTable ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
nBitMod1 = 9;
|
||||||
|
nBitMask = bitMasks[nBitMod1];
|
||||||
|
maxCode = 1 << nBitMod1;
|
||||||
|
freeCode = FIRST_FREE_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private int readCode ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
int bitIdx = bitOffset & 0x07;
|
||||||
|
int byteIdx = bitOffset >>> 3; // no sign extension
|
||||||
|
|
||||||
|
int iCode = srcBuf[byteIdx] & 0xFF | (srcBuf[byteIdx + 1] & 0xFF) << 8
|
||||||
|
| (srcBuf[byteIdx + 2] & 0xFF) << 16;
|
||||||
|
|
||||||
|
iCode >>>= bitIdx;
|
||||||
|
iCode &= nBitMask;
|
||||||
|
|
||||||
|
bitOffset += nBitMod1;
|
||||||
|
|
||||||
|
return iCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private void addCode ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
hashChar[freeCode] = k;
|
||||||
|
hashNext[freeCode] = oldCode;
|
||||||
|
freeCode++;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
package com.bytezone.diskbrowser.utilities;
|
package com.bytezone.diskbrowser.nufx;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.utilities.DateTime;
|
||||||
|
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
||||||
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
class MasterHeader
|
public class MasterHeader
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final byte[] NuFile =
|
private static final byte[] NuFile = { 0x4E, (byte) 0xF5, 0x46, (byte) 0xE9, 0x6C, (byte) 0xE5 };
|
||||||
{ 0x4E, (byte) 0xF5, 0x46, (byte) 0xE9, 0x6C, (byte) 0xE5 };
|
|
||||||
private static final byte[] BIN2 = { 0x0A, 0x47, 0x4C };
|
private static final byte[] BIN2 = { 0x0A, 0x47, 0x4C };
|
||||||
|
|
||||||
private final int crc;
|
private final int crc;
|
||||||
@ -30,15 +34,6 @@ class MasterHeader
|
|||||||
if (Utility.isMagic (buffer, ptr, NuFile))
|
if (Utility.isMagic (buffer, ptr, NuFile))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// internet.shk has 0x2000 bytes of text at the start
|
|
||||||
// if (Utility.isMagic (buffer, 0x2000, NuFile))
|
|
||||||
// {
|
|
||||||
// System.out.println ("found it");
|
|
||||||
// ptr = 0x2000;
|
|
||||||
// bin2 = true;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (isBin2 (buffer, ptr))
|
if (isBin2 (buffer, ptr))
|
||||||
{
|
{
|
||||||
binary2Header = new Binary2Header (buffer, 0);
|
binary2Header = new Binary2Header (buffer, 0);
|