This commit is contained in:
Martin Haye 2016-02-01 08:07:19 -08:00
commit c0e98cd6c4
11 changed files with 173 additions and 52 deletions

View File

@ -6,6 +6,12 @@
<name>OutlawEditor</name> <name>OutlawEditor</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mainClass>org.badvision.outlaweditor.Application</mainClass>
<netbeans.hint.license>apache20</netbeans.hint.license>
</properties>
<organization> <organization>
<!-- Used as the 'Vendor' for JNLP generation --> <!-- Used as the 'Vendor' for JNLP generation -->
<name>org.badvision</name> <name>org.badvision</name>
@ -14,27 +20,52 @@
<finalName>OutlawEditor</finalName> <finalName>OutlawEditor</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>com.zenjava</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>javafx-maven-plugin</artifactId> <artifactId>maven-dependency-plugin</artifactId>
<version>8.1.2</version> <version>2.10</version>
<configuration>
outlawEditor
<mainClass>org.badvision.outlaweditor.Application</mainClass>
<!-- only required if signing the jar file -->
<keyStoreAlias>example-user</keyStoreAlias>
<keyStorePassword>example-password</keyStorePassword>
<allPermissions>true</allPermissions>
<bundleType>ALL</bundleType>
</configuration>
<executions> <executions>
<execution> <execution>
<id>package</id> <id>unpack-dependencies</id>
<phase>package</phase> <phase>package</phase>
<goals> <goals>
<goal>jar</goal> <goal>unpack-dependencies</goal>
</goals> </goals>
<configuration>
<excludeScope>system</excludeScope>
<excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution> </execution>
</executions> </executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${java.home}/../bin/javapackager</executable>
<arguments>
<argument>-createjar</argument>
<argument>-nocss2bin</argument>
<argument>-appclass</argument>
<argument>${mainClass}</argument>
<argument>-srcdir</argument>
<argument>${project.build.directory}/classes</argument>
<argument>-outdir</argument>
<argument>${project.build.directory}</argument>
<argument>-outfile</argument>
<argument>${project.build.finalName}.jar</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -43,12 +74,12 @@
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>
</configuration> </configuration>
<version>3.1</version> <version>3.5</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId> <groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId> <artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.3</version> <version>0.13.1</version>
<executions> <executions>
<execution> <execution>
<goals> <goals>
@ -60,6 +91,17 @@
</schemaIncludes> </schemaIncludes>
<episodeFile>${project.build.directory}/generated-sources/xjc/META-INF/jaxb-OutlawSchema.episode</episodeFile> <episodeFile>${project.build.directory}/generated-sources/xjc/META-INF/jaxb-OutlawSchema.episode</episodeFile>
<generatePackage>org.badvision.outlaweditor.data.xml</generatePackage> <generatePackage>org.badvision.outlaweditor.data.xml</generatePackage>
<args>
<arg>-Xcopyable</arg>
<arg>-Xmergeable</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.11.0</version>
</plugin>
</plugins>
</configuration> </configuration>
<id>jaxb-generate-OutlawSchema</id> <id>jaxb-generate-OutlawSchema</id>
</execution> </execution>
@ -69,7 +111,7 @@
</build> </build>
<dependencies> <dependencies>
<!-- <dependency> <!-- <dependency>
<groupId>com.oracle</groupId> <groupId>com.oracle</groupId>
<artifactId>javafx</artifactId> <artifactId>javafx</artifactId>
<version>2</version> <version>2</version>
@ -86,9 +128,14 @@
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.11</version> <version>4.12</version>
<scope>test</scope> <scope>test</scope>
<type>jar</type> <type>jar</type>
</dependency> </dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.11.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -10,10 +10,15 @@
package org.badvision.outlaweditor; package org.badvision.outlaweditor;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javax.xml.bind.JAXBException;
import org.badvision.outlaweditor.data.DataObserver; import org.badvision.outlaweditor.data.DataObserver;
import org.badvision.outlaweditor.data.DataProducer; import org.badvision.outlaweditor.data.DataProducer;
import org.badvision.outlaweditor.data.xml.Script; import org.badvision.outlaweditor.data.xml.Script;
import org.jvnet.jaxb2_commons.lang.CopyTo2;
/** /**
* Extremely generic editor abstraction -- useful for uniform edit features * Extremely generic editor abstraction -- useful for uniform edit features
@ -22,12 +27,15 @@ import org.badvision.outlaweditor.data.xml.Script;
* @author brobert * @author brobert
*/ */
public abstract class Editor<T, D> implements DataObserver<T> { public abstract class Editor<T, D> implements DataObserver<T> {
public static final int UNDO_HISTORY_LENGTH = 50;
LinkedList<T> undoStates = new LinkedList<>();
T editEntity; T editEntity;
public void setEntity(T t) { public void setEntity(T t) {
editEntity = t; editEntity = t;
DataProducer.addObserver(t, this); DataProducer.addObserver(t, this);
onEntityUpdated();
} }
public T getEntity() { public T getEntity() {
@ -84,4 +92,28 @@ public abstract class Editor<T, D> implements DataObserver<T> {
} }
abstract public void redraw(); abstract public void redraw();
protected void trackState() {
if (undoStates.size() >= UNDO_HISTORY_LENGTH) {
undoStates.removeLast();
}
try {
undoStates.push(TransferHelper.cloneObject(getEntity(), (Class<T>) getEntity().getClass(), getEntity().getClass().getName()));
} catch (JAXBException ex) {
Logger.getLogger(Editor.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void undo() {
if (!undoStates.isEmpty()) {
CopyTo2 undoState = (CopyTo2) undoStates.removeFirst();
undoState.copyTo(getEntity());
onEntityUpdated();
redraw();
}
}
protected void onEntityUpdated() {
}
} }

View File

@ -7,7 +7,6 @@
* ANY KIND, either express or implied. See the License for the specific language * ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License. * governing permissions and limitations under the License.
*/ */
package org.badvision.outlaweditor; package org.badvision.outlaweditor;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -19,6 +18,8 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.DataFormatException; import java.util.zip.DataFormatException;
import java.util.zip.Deflater; import java.util.zip.Deflater;
import java.util.zip.Inflater; import java.util.zip.Inflater;
@ -30,6 +31,9 @@ import javafx.stage.FileChooser;
*/ */
public class FileUtils { public class FileUtils {
private FileUtils() {
}
public static enum Extension { public static enum Extension {
XML("XML files", "xml"), XML("XML files", "xml"),
@ -64,7 +68,9 @@ public class FileUtils {
} }
if (create) { if (create) {
File file = f.showSaveDialog(Application.getPrimaryStage()); File file = f.showSaveDialog(Application.getPrimaryStage());
if (file == null) return null; if (file == null) {
return null;
}
if (!file.getName().contains(".")) { if (!file.getName().contains(".")) {
return new File(file.getParentFile(), file.getName() + "." + supportedExtensions[0].extension); return new File(file.getParentFile(), file.getName() + "." + supportedExtensions[0].extension);
} else { } else {
@ -132,8 +138,8 @@ public class FileUtils {
} }
public static byte[] decompress(byte[] bytesToDecompress) { public static byte[] decompress(byte[] bytesToDecompress) {
int numberOfBytesToDecompress = bytesToDecompress.length;
try { try {
int numberOfBytesToDecompress = bytesToDecompress.length;
Inflater inflater = new Inflater(); Inflater inflater = new Inflater();
inflater.setInput( inflater.setInput(
bytesToDecompress, bytesToDecompress,
@ -152,9 +158,9 @@ public class FileUtils {
numberOfBytesAfterDecompression); numberOfBytesAfterDecompression);
inflater.end(); inflater.end();
return returnValues; return returnValues;
} catch (DataFormatException dfe) { } catch (DataFormatException ex) {
dfe.printStackTrace(System.err); Logger.getLogger(FileUtils.class.getName()).log(Level.SEVERE, null, ex);
return null;
} }
return null;
} }
} }

View File

@ -69,9 +69,8 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
double tileHeight = currentPlatform.tileRenderer.getHeight() * zoom; double tileHeight = currentPlatform.tileRenderer.getHeight() * zoom;
@Override @Override
public void setEntity(Map t) { protected void onEntityUpdated() {
super.setEntity(t); currentMap = new TileMap(getEntity());
currentMap = new TileMap(t);
} }
public TileMap getCurrentMap() { public TileMap getCurrentMap() {
@ -557,6 +556,12 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
DrawMode lastDrawMode = null; DrawMode lastDrawMode = null;
Tile lastTile = null; Tile lastTile = null;
@Override
protected void trackState() {
currentMap.updateBackingMap();
super.trackState();
}
@Override @Override
public void handle(MouseEvent t) { public void handle(MouseEvent t) {
updateCursorAssistant(t); updateCursorAssistant(t);
@ -580,6 +585,7 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
if (canSkip) { if (canSkip) {
return; return;
} }
trackState();
plot(x,y,null); plot(x,y,null);
redraw(); redraw();
break; break;
@ -588,22 +594,26 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
if (canSkip) { if (canSkip) {
return; return;
} }
trackState();
plot(x, y, getCurrentTile()); plot(x, y, getCurrentTile());
break; break;
case Pencil3px: case Pencil3px:
if (canSkip) { if (canSkip) {
return; return;
} }
trackState();
drawBrush(x, y, 2, getCurrentTile()); drawBrush(x, y, 2, getCurrentTile());
break; break;
case Pencil5px: case Pencil5px:
if (canSkip) { if (canSkip) {
return; return;
} }
trackState();
drawBrush(x, y, 5, getCurrentTile()); drawBrush(x, y, 5, getCurrentTile());
break; break;
case FilledRect: case FilledRect:
if (t.getEventType().equals(MouseEvent.MOUSE_RELEASED)) { if (t.getEventType().equals(MouseEvent.MOUSE_RELEASED)) {
trackState();
fillSelection(t.getX(), t.getY()); fillSelection(t.getX(), t.getY());
} else if (t.isPrimaryButtonDown()) { } else if (t.isPrimaryButtonDown()) {
updateSelection(t.getX(), t.getY()); updateSelection(t.getX(), t.getY());

View File

@ -33,10 +33,10 @@ import org.badvision.outlaweditor.Application;
import org.badvision.outlaweditor.FileUtils; import org.badvision.outlaweditor.FileUtils;
import org.badvision.outlaweditor.ImageEditor; import org.badvision.outlaweditor.ImageEditor;
import org.badvision.outlaweditor.Platform; import org.badvision.outlaweditor.Platform;
import org.badvision.outlaweditor.ui.UIAction;
import org.badvision.outlaweditor.data.TileMap; import org.badvision.outlaweditor.data.TileMap;
import org.badvision.outlaweditor.data.xml.Image; import org.badvision.outlaweditor.data.xml.Image;
import org.badvision.outlaweditor.data.xml.PlatformData; import org.badvision.outlaweditor.data.xml.PlatformData;
import org.badvision.outlaweditor.ui.UIAction;
/** /**
* *
@ -61,6 +61,12 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
return Platform.AppleII; return Platform.AppleII;
} }
@Override
protected void onEntityUpdated() {
super.onEntityUpdated();
data = null;
}
@Override @Override
public void buildEditorUI(Pane editorAnchorPane) { public void buildEditorUI(Pane editorAnchorPane) {
anchorPane = editorAnchorPane; anchorPane = editorAnchorPane;
@ -145,28 +151,24 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
currentImage = getPlatform().imageRenderer.renderImage(currentImage, getImageData(), getWidth(), getHeight()); currentImage = getPlatform().imageRenderer.renderImage(currentImage, getImageData(), getWidth(), getHeight());
} }
private byte[] imageData = null; PlatformData data = null;
public PlatformData getPlatformData() {
public byte[] getImageData() { if (data == null) {
if (imageData == null) { data = getPlatformData(getPlatform());
PlatformData data = getPlatformData(getPlatform());
if (data == null) { if (data == null) {
createNewPlatformImage(getPlatform().maxImageWidth, getPlatform().maxImageHeight); createNewPlatformImage(getPlatform().maxImageWidth, getPlatform().maxImageHeight);
data = getPlatformData(getPlatform()); data = getPlatformData(getPlatform());
} }
imageData = data.getValue();
} }
return imageData; return data;
}
public byte[] getImageData() {
return getPlatformData().getValue();
} }
public void setData(byte[] data) { public void setData(byte[] data) {
imageData = data; getPlatformData().setValue(data);
for (PlatformData d : getEntity().getDisplayData()) {
if (d.getPlatform().equalsIgnoreCase(getPlatform().name())) {
d.setValue(data);
break;
}
}
} }
public void setDataAndRedraw(byte[] data) { public void setDataAndRedraw(byte[] data) {
@ -242,6 +244,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
if (canSkip) { if (canSkip) {
return false; return false;
} }
trackState();
if (alt) { if (alt) {
toggleHiBit(x, y); toggleHiBit(x, y);
} else { } else {
@ -253,6 +256,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
if (canSkip) { if (canSkip) {
return false; return false;
} }
trackState();
plot(x, y, currentFillPattern, hiBitMatters); // [ref BigBlue1_30] plot(x, y, currentFillPattern, hiBitMatters); // [ref BigBlue1_30]
redrawScanline(y); redrawScanline(y);
break; break;
@ -260,12 +264,14 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
if (canSkip) { if (canSkip) {
return false; return false;
} }
trackState();
drawBrush(x, y, 3, currentFillPattern, hiBitMatters); drawBrush(x, y, 3, currentFillPattern, hiBitMatters);
break; break;
case Pencil5px: case Pencil5px:
if (canSkip) { if (canSkip) {
return false; return false;
} }
trackState();
drawBrush(x, y, 5, currentFillPattern, hiBitMatters); drawBrush(x, y, 5, currentFillPattern, hiBitMatters);
break; break;
case Rectangle: case Rectangle:

View File

@ -10,7 +10,6 @@
package org.badvision.outlaweditor.apple; package org.badvision.outlaweditor.apple;
import javafx.event.EventHandler;
import javafx.scene.Group; import javafx.scene.Group;
import javafx.scene.control.Menu; import javafx.scene.control.Menu;
import javafx.scene.image.WritableImage; import javafx.scene.image.WritableImage;
@ -22,8 +21,8 @@ import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape; import javafx.scene.shape.Shape;
import org.badvision.outlaweditor.Platform; import org.badvision.outlaweditor.Platform;
import org.badvision.outlaweditor.TileEditor; import org.badvision.outlaweditor.TileEditor;
import org.badvision.outlaweditor.data.xml.Tile;
import org.badvision.outlaweditor.data.TileUtils; import org.badvision.outlaweditor.data.TileUtils;
import org.badvision.outlaweditor.data.xml.Tile;
/** /**
* *
@ -99,6 +98,7 @@ public class AppleTileEditor extends TileEditor {
debounceTime = System.currentTimeMillis() + SAFE_WAIT_TIME; debounceTime = System.currentTimeMillis() + SAFE_WAIT_TIME;
lastActionX = x; lastActionX = x;
lastActionY = y; lastActionY = y;
trackState();
switch (drawMode) { switch (drawMode) {
case Toggle: case Toggle:
if (alt) { if (alt) {

View File

@ -7,7 +7,6 @@
* ANY KIND, either express or implied. See the License for the specific language * ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License. * governing permissions and limitations under the License.
*/ */
package org.badvision.outlaweditor.data; package org.badvision.outlaweditor.data;
import java.io.Serializable; import java.io.Serializable;
@ -95,7 +94,7 @@ public class TileMap extends ArrayList<ArrayList<Tile>> implements Serializable
private void registerLocationScript(int x, int y, Script s) { private void registerLocationScript(int x, int y, Script s) {
if (!scriptColors.containsKey(s)) { if (!scriptColors.containsKey(s)) {
scriptColors.put(s, Color.hsb(HUE, SATURATION, 0.75 + Math.cos(HUE / Math.PI / 2.0)/8.0)); scriptColors.put(s, Color.hsb(HUE, SATURATION, 0.75 + Math.cos(HUE / Math.PI / 2.0) / 8.0));
HUE = (HUE + 27) % 360; HUE = (HUE + 27) % 360;
} }
int loc = getMortonNumber(x, y); int loc = getMortonNumber(x, y);
@ -178,7 +177,8 @@ public class TileMap extends ArrayList<ArrayList<Tile>> implements Serializable
Set<Tile> unknownTiles = new HashSet<>(); Set<Tile> unknownTiles = new HashSet<>();
Scripts scripts = m.getScripts(); Scripts scripts = m.getScripts();
if (scripts != null) { if (scripts != null) {
scripts.getScript().forEach( List<Script> allScripts = new ArrayList<>(scripts.getScript());
allScripts.forEach(
s -> s.getLocationTrigger().forEach( s -> s.getLocationTrigger().forEach(
l -> registerLocationScript(l.getX(), l.getY(), s) l -> registerLocationScript(l.getX(), l.getY(), s)
) )

View File

@ -58,4 +58,7 @@ public abstract class ApplicationMenuController {
@FXML @FXML
abstract public void onHelpAbout(ActionEvent event); abstract public void onHelpAbout(ActionEvent event);
@FXML
abstract public void performUndo(ActionEvent event);
} }

View File

@ -15,6 +15,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import org.badvision.outlaweditor.Application; import org.badvision.outlaweditor.Application;
import org.badvision.outlaweditor.Editor;
import org.badvision.outlaweditor.Platform; import org.badvision.outlaweditor.Platform;
import org.badvision.outlaweditor.apple.AppleTileRenderer; import org.badvision.outlaweditor.apple.AppleTileRenderer;
import org.badvision.outlaweditor.ui.ApplicationMenuController; import org.badvision.outlaweditor.ui.ApplicationMenuController;
@ -127,4 +128,12 @@ public class ApplicationMenuControllerImpl extends ApplicationMenuController {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
} }
@Override
public void performUndo(ActionEvent event) {
Editor editor = ApplicationUIController.getController().getVisibleEditor();
if (editor != null) {
editor.undo();
}
}
} }

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.input.*?>
<?import java.lang.*?> <?import java.lang.*?>
<?import java.util.*?> <?import java.util.*?>
<?import javafx.scene.*?> <?import javafx.scene.*?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<MenuBar styleClass="menu" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.badvision.outlaweditor.ui.impl.ApplicationMenuControllerImpl"> <MenuBar styleClass="menu" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.badvision.outlaweditor.ui.impl.ApplicationMenuControllerImpl">
<menus> <menus>
<Menu mnemonicParsing="false" text="File"> <Menu mnemonicParsing="false" text="File">
<items> <items>
@ -21,6 +22,11 @@
<MenuItem mnemonicParsing="false" onAction="#onEditSelect" text="Select" /> <MenuItem mnemonicParsing="false" onAction="#onEditSelect" text="Select" />
<MenuItem mnemonicParsing="false" onAction="#onEditCopy" text="Copy" /> <MenuItem mnemonicParsing="false" onAction="#onEditCopy" text="Copy" />
<MenuItem mnemonicParsing="false" onAction="#onEditPaste" text="Paste" /> <MenuItem mnemonicParsing="false" onAction="#onEditPaste" text="Paste" />
<MenuItem mnemonicParsing="false" onAction="#performUndo" text="Undo">
<accelerator>
<KeyCodeCombination alt="UP" code="Z" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
</accelerator>
</MenuItem>
<Menu mnemonicParsing="false" text="Change Platform"> <Menu mnemonicParsing="false" text="Change Platform">
<items> <items>
<MenuItem mnemonicParsing="false" onAction="#onChangePlatformAppleSolid" text="Apple (solid)" /> <MenuItem mnemonicParsing="false" onAction="#onChangePlatformAppleSolid" text="Apple (solid)" />
@ -38,4 +44,4 @@
</items> </items>
</Menu> </Menu>
</menus> </menus>
</MenuBar> </MenuBar>

View File

@ -614,8 +614,10 @@ void interp(code *ip)
ea = POP; ea = POP;
PUSH(ea >> val); PUSH(ea >> val);
break; break;
case 0x1E: // IDXW : TOS = TOS * 2 case 0x1E: // IDXW : TOS = TOS * 2 + TOS-1
TOS *= 2; val = POP;
ea = POP;
PUSH(ea + val * 2);
break; break;
/* /*
* 0x20-0x2F * 0x20-0x2F