From ea345993f3ad45f43b7bcf7dcff2e02bb939e064 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Mon, 13 Jan 2020 10:05:32 +1000 Subject: [PATCH] Save selected sectors --- .../bytezone/diskbrowser/gui/DiskBrowser.java | 14 ++++- .../bytezone/diskbrowser/gui/MenuHandler.java | 30 ++++++++-- .../diskbrowser/gui/SaveSectorsAction.java | 59 +++++++++++++++++++ .../diskbrowser/gui/SaveTempFileAction.java | 9 ++- .../bytezone/diskbrowser/gui/WindowSaver.java | 12 +++- .../diskbrowser/infocom/CodeManager.java | 6 ++ .../diskbrowser/infocom/Dictionary.java | 7 ++- .../bytezone/diskbrowser/infocom/Globals.java | 12 ++-- .../diskbrowser/infocom/Instruction.java | 36 ++++++----- 9 files changed, 152 insertions(+), 33 deletions(-) create mode 100644 src/com/bytezone/diskbrowser/gui/SaveSectorsAction.java diff --git a/src/com/bytezone/diskbrowser/gui/DiskBrowser.java b/src/com/bytezone/diskbrowser/gui/DiskBrowser.java index b4b5667..7033530 100755 --- a/src/com/bytezone/diskbrowser/gui/DiskBrowser.java +++ b/src/com/bytezone/diskbrowser/gui/DiskBrowser.java @@ -10,7 +10,14 @@ import java.util.ArrayList; import java.util.List; import java.util.prefs.Preferences; -import javax.swing.*; +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JToolBar; +import javax.swing.UIManager; import com.bytezone.diskbrowser.duplicates.RootFolderData; @@ -33,7 +40,6 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi // ---------------------------------------------------------------------------------// { super (windowTitle); - // System.out.printf ("Start Init: %,5d%n", System.currentTimeMillis () - start); if (args.length > 0 && "-reset".equals (args[0])) new WindowState (prefs).clear (); @@ -107,6 +113,8 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi diskLayoutPanel.addSectorSelectionListener (dataPanel); diskLayoutPanel.addSectorSelectionListener (redoHandler); diskLayoutPanel.addSectorSelectionListener (catalogPanel); + diskLayoutPanel.addSectorSelectionListener (menuHandler); + diskLayoutPanel.addSectorSelectionListener (menuHandler.saveSectorsAction); duplicateAction.addTableSelectionListener (catalogPanel); @@ -166,6 +174,7 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi // restore the menuHandler items before they are referenced fireRestoreEvent (); + diskLayoutPanel.setFree (menuHandler.showFreeSectorsItem.isSelected ()); dataPanel.setLineWrap (menuHandler.lineWrapItem.isSelected ()); @@ -180,7 +189,6 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi // activate the highest panel now that the listeners are ready catalogPanel.activate (); - // System.out.printf ("End Init : %,5d%n", System.currentTimeMillis () - start); } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/gui/MenuHandler.java b/src/com/bytezone/diskbrowser/gui/MenuHandler.java index cfe7cd1..7f4f986 100755 --- a/src/com/bytezone/diskbrowser/gui/MenuHandler.java +++ b/src/com/bytezone/diskbrowser/gui/MenuHandler.java @@ -8,16 +8,28 @@ import java.util.Enumeration; import java.util.List; import java.util.prefs.Preferences; -import javax.swing.*; +import javax.swing.AbstractButton; +import javax.swing.ButtonGroup; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.KeyStroke; import com.bytezone.common.FontAction; -import com.bytezone.diskbrowser.applefile.*; +import com.bytezone.diskbrowser.applefile.AssemblerProgram; +import com.bytezone.diskbrowser.applefile.BasicProgram; +import com.bytezone.diskbrowser.applefile.HiResImage; +import com.bytezone.diskbrowser.applefile.Palette; +import com.bytezone.diskbrowser.applefile.PaletteFactory; +import com.bytezone.diskbrowser.applefile.VisicalcFile; import com.bytezone.diskbrowser.disk.DataDisk; import com.bytezone.diskbrowser.disk.FormattedDisk; import com.bytezone.diskbrowser.prodos.ProdosDisk; -public class MenuHandler - implements DiskSelectionListener, FileSelectionListener, QuitListener +public class MenuHandler implements DiskSelectionListener, FileSelectionListener, + QuitListener, SectorSelectionListener { static final String PREFS_LINE_WRAP = "line wrap"; private static final String PREFS_SHOW_CATALOG = "show catalog"; @@ -44,6 +56,7 @@ public class MenuHandler FormattedDisk currentDisk; private final SaveTempFileAction saveTempFileAction = new SaveTempFileAction (); + final SaveSectorsAction saveSectorsAction = new SaveSectorsAction (); private final BasicPreferences basicPreferences = new BasicPreferences (); private final List basicPreferencesListeners = @@ -71,6 +84,7 @@ public class MenuHandler final JMenuItem refreshTreeItem = new JMenuItem ("Refresh current tree"); JMenuItem executeDiskItem; final JMenuItem saveDiskItem = new JMenuItem ("Save converted disk as..."); + final JMenuItem saveSectorsItem = new JMenuItem ("Save sectors as..."); final JMenuItem printItem = new JMenuItem ("Print output panel..."); final JMenuItem closeTabItem = new JMenuItem (); final JMenuItem duplicateItem = new JMenuItem (); @@ -128,6 +142,7 @@ public class MenuHandler fileMenu.addSeparator (); fileMenu.add (refreshTreeItem); fileMenu.add (saveDiskItem); + fileMenu.add (saveSectorsItem); addLauncherMenu (); @@ -252,6 +267,7 @@ public class MenuHandler interleaveGroup.add (interleave3Item); saveDiskItem.setAction (saveTempFileAction); + saveSectorsItem.setAction (saveSectorsAction); } private void setBasicPreferences () @@ -500,4 +516,10 @@ public class MenuHandler saveDiskItem.setEnabled (disk.isTempDisk ()); saveTempFileAction.setDisk (disk); } + + @Override + public void sectorSelected (SectorSelectedEvent event) + { + // List sectors = event.getSectors (); + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/gui/SaveSectorsAction.java b/src/com/bytezone/diskbrowser/gui/SaveSectorsAction.java new file mode 100644 index 0000000..1291c51 --- /dev/null +++ b/src/com/bytezone/diskbrowser/gui/SaveSectorsAction.java @@ -0,0 +1,59 @@ +package com.bytezone.diskbrowser.gui; + +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; + +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; + +import com.bytezone.common.DefaultAction; + +public class SaveSectorsAction extends DefaultAction implements SectorSelectionListener +{ + SectorSelectedEvent event; + + public SaveSectorsAction () + { + super ("Save sectors...", "Save sectors"); + this.setEnabled (false); + } + + @Override + public void actionPerformed (ActionEvent evt) + { + if (event == null) + { + System.out.println ("No sectors"); + return; + } + byte[] buffer = + event.getFormattedDisk ().getDisk ().readSectors (event.getSectors ()); + + JFileChooser fileChooser = new JFileChooser (); + fileChooser.setDialogTitle ("Save sectors"); + fileChooser.setSelectedFile (new File ("saved-" + buffer.length + ".bin")); + if (fileChooser.showSaveDialog (null) == JFileChooser.APPROVE_OPTION) + { + File file = fileChooser.getSelectedFile (); + try + { + Files.write (file.toPath (), buffer, StandardOpenOption.CREATE_NEW); + JOptionPane.showMessageDialog (null, "File saved"); + } + catch (IOException e) + { + e.printStackTrace (); + } + } + } + + @Override + public void sectorSelected (SectorSelectedEvent event) + { + this.event = event; + this.setEnabled (true); + } +} diff --git a/src/com/bytezone/diskbrowser/gui/SaveTempFileAction.java b/src/com/bytezone/diskbrowser/gui/SaveTempFileAction.java index 6ba18da..91e8773 100644 --- a/src/com/bytezone/diskbrowser/gui/SaveTempFileAction.java +++ b/src/com/bytezone/diskbrowser/gui/SaveTempFileAction.java @@ -17,12 +17,18 @@ public class SaveTempFileAction extends DefaultAction public SaveTempFileAction () { - super ("Save converted file...", "Save converted file"); + super ("Save converted disk...", "Save converted disk"); } @Override public void actionPerformed (ActionEvent evt) { + if (disk == null) + { + System.out.println ("No disk"); + return; + } + JFileChooser fileChooser = new JFileChooser (); fileChooser.setDialogTitle ("Save converted disk"); String name = disk.getName (); @@ -45,5 +51,6 @@ public class SaveTempFileAction extends DefaultAction void setDisk (FormattedDisk disk) { this.disk = disk; + this.setEnabled (true); } } diff --git a/src/com/bytezone/diskbrowser/gui/WindowSaver.java b/src/com/bytezone/diskbrowser/gui/WindowSaver.java index 465d8f9..546f264 100644 --- a/src/com/bytezone/diskbrowser/gui/WindowSaver.java +++ b/src/com/bytezone/diskbrowser/gui/WindowSaver.java @@ -35,6 +35,14 @@ public class WindowSaver Dimension screen = java.awt.Toolkit.getDefaultToolkit ().getScreenSize (); + if (false) + { + System.out.printf ("Screen height ..... %d%n", screen.height); + System.out.printf ("Screen width ...... %d%n", screen.width); + System.out.printf ("Window height ..... %d%n", height); + System.out.printf ("Window width ...... %d%n", width); + } + if (width < 0) // nothing to restore { frame.setLocation (100, 100); @@ -43,8 +51,8 @@ public class WindowSaver return false; } - if (width > screen.getWidth () - 15) - width = (int) (screen.getWidth () - 15); + if (width > screen.getWidth ()) + width = (int) (screen.getWidth ()); frame.setSize (width, height); frame.setLocation (x, y); diff --git a/src/com/bytezone/diskbrowser/infocom/CodeManager.java b/src/com/bytezone/diskbrowser/infocom/CodeManager.java index 710f43c..4e99d4b 100644 --- a/src/com/bytezone/diskbrowser/infocom/CodeManager.java +++ b/src/com/bytezone/diskbrowser/infocom/CodeManager.java @@ -67,6 +67,7 @@ class CodeManager extends AbstractFile addRoutine (programCounter - 1, -1); addActionRoutines (); // obtained from Grammar addCodeRoutines (); // obtained from Object properties + addGlobalRoutines (); addMissingRoutines (); // requires stringPtr to be set // checkThreeByteProperties (); @@ -117,6 +118,11 @@ class CodeManager extends AbstractFile return ptr; } + private void addGlobalRoutines () + { + + } + private void addMissingRoutines () { System.out.printf ("%nWalking the code block%n%n"); diff --git a/src/com/bytezone/diskbrowser/infocom/Dictionary.java b/src/com/bytezone/diskbrowser/infocom/Dictionary.java index 1d86cf4..40020f7 100755 --- a/src/com/bytezone/diskbrowser/infocom/Dictionary.java +++ b/src/com/bytezone/diskbrowser/infocom/Dictionary.java @@ -255,7 +255,11 @@ class Dictionary extends AbstractFile for (int bit = 1; bit < 256; bit *= 2) { - text.append (String.format ("Bit: %d%n", bit)); + String bits = Integer.toBinaryString (bit & 0xFF); + if (bits.length () < 8) + bits = "00000000".substring (bits.length ()) + bits; + + text.append (String.format ("Bits: %s%n", bits)); for (List list : synonymList.values ()) { WordEntry wordEntry = list.get (0); @@ -270,7 +274,6 @@ class Dictionary extends AbstractFile { for (WordEntry we : list) text.append (we + "\n"); - // text.deleteCharAt (text.length () - 1); } else text.append (wordEntry + "\n"); diff --git a/src/com/bytezone/diskbrowser/infocom/Globals.java b/src/com/bytezone/diskbrowser/infocom/Globals.java index 5b56c3b..9d5a55f 100644 --- a/src/com/bytezone/diskbrowser/infocom/Globals.java +++ b/src/com/bytezone/diskbrowser/infocom/Globals.java @@ -27,15 +27,14 @@ class Globals extends InfocomAbstractFile hexBlocks.add (new HexBlock (globalsPtr, globalsSize, "Globals:")); hexBlocks.add (new HexBlock (arrayPtr, arraySize, "Arrays:")); - globalRoutines = new ArrayList<> (250); - for (int i = 0; i < 250; i++) + globalRoutines = new ArrayList<> (TOTAL_GLOBALS); + for (int i = 0; i < TOTAL_GLOBALS; i++) globalRoutines.add (new ArrayList<> ()); } void addRoutine (Routine routine, Operand operand) { - int global = operand.value - 15; - List list = globalRoutines.get (global); + List list = globalRoutines.get (operand.value - 16); if (!list.contains (routine)) list.add (routine); } @@ -44,10 +43,10 @@ class Globals extends InfocomAbstractFile public String getText () { StringBuilder text = new StringBuilder ("GLB Value Routines\n"); - for (int i = 1; i <= TOTAL_GLOBALS; i++) + for (int i = 0; i < TOTAL_GLOBALS; i++) { int value = header.getWord (globalsPtr + i * 2); - text.append (String.format ("G%03d %04X %02d ", i, value, + text.append (String.format ("G%03d %04X %03d ", i, value, globalRoutines.get (i).size ())); int address = value * 2; if (address >= header.stringPointer && address < header.fileLength) @@ -58,7 +57,6 @@ class Globals extends InfocomAbstractFile text.append (String.format ("%05X ", routine.startPtr)); text.append ("\n"); } - // text.append (String.format ("%,6d%n", value)); } text.deleteCharAt (text.length () - 1); return text.toString (); diff --git a/src/com/bytezone/diskbrowser/infocom/Instruction.java b/src/com/bytezone/diskbrowser/infocom/Instruction.java index 9a13ccf..22d78d9 100755 --- a/src/com/bytezone/diskbrowser/infocom/Instruction.java +++ b/src/com/bytezone/diskbrowser/infocom/Instruction.java @@ -7,6 +7,8 @@ import com.bytezone.diskbrowser.utilities.HexFormatter; class Instruction { + static int version = 3; + final Opcode opcode; final int startPtr; private byte[] buffer; @@ -45,21 +47,27 @@ class Instruction this.header = header; byte b1 = buffer[ptr]; - if ((b1 & 0x80) == 0) // long - opcode = new Opcode2OPLong (buffer, ptr); - else if ((b1 & 0x40) == 0) // short + int type = (b1 & 0xC0) >>> 6; + switch (type) { - if ((b1 & 0x30) == 0x30) - opcode = new Opcode0OP (buffer, ptr); - else - opcode = new Opcode1OP (buffer, ptr); - } - else // variable - { - if ((b1 & 0x20) == 0) - opcode = new Opcode2OPVar (buffer, ptr); - else - opcode = new OpcodeVar (buffer, ptr); + case 0x03: // 11 - variable + if ((b1 & 0x20) == 0x20) + opcode = new OpcodeVar (buffer, ptr); + else + opcode = new Opcode2OPVar (buffer, ptr); + break; + + case 0x02: // 10 - extended or short + if (b1 == 0xBE && version >= 5) + opcode = null; + else if ((b1 & 0x30) == 0x30) + opcode = new Opcode0OP (buffer, ptr); + else + opcode = new Opcode1OP (buffer, ptr); + break; + + default: // 00, 01 - long + opcode = new Opcode2OPLong (buffer, ptr); } }