This commit is contained in:
Martin Haye 2014-12-21 08:17:26 -08:00
commit bc73588a20
36 changed files with 1794 additions and 1469 deletions

View File

@ -1,16 +1,16 @@
Outlaw Editor
=============
This is a multi-platform RPG game editor. It is written in (and requires) Java 7 and JavaFX 2.2 to run. There are no external dependencies, but it is important that you install JavaFX 2.2 as per Oracle's instructions so that the java runtime can find the JavaFX libraries automatically.
This is a multi-platform RPG game editor. It is written in (and requires) Java 8 to run. There are no external dependencies.
Download
--------
The most recent copy of Outlaw Editor (aka the Daily build) can be found here: https://www.dropbox.com/s/2bhoxqrqjjehmqb/OutlawEditor-jfx.jar
The most recent copy of Outlaw Editor (aka the Daily build) can be found here: https://www.dropbox.com/s/zrystud66myzlwa/OutlawEditor-jfx.jar
Running the program
-------------------
There are no dependencies outside of JavaFX (which will be part of Java in the 8.0 release) so you can start the program by executing the jar file that is built in the target/jfx/app folder "OutlawEditor-jfx.jar" Depending on your platform you might be able to double-click it. Or you might have to drop to the commandline and issue this command after going to that directory, like so:
You can start the program by executing the jar file that is built in the target/jfx/app folder "OutlawEditor-jfx.jar" Depending on your platform you might be able to double-click it. Or you might have to drop to the commandline and issue this command after going to that directory, like so:
> java -jar OutlawEditor-jfx.jar

View File

@ -1,554 +0,0 @@
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x000000012c91e56b, pid=3251, tid=65539
#
# JRE version: Java(TM) SE Runtime Environment (7.0_40-b40) (build 1.7.0_40-b40)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.0-b55 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C [libgstplugins-lite.dylib+0x1156b] gst_iir_equalizer_compute_frequencies+0x285
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- T H R E A D ---------------
Current thread (0x00007fdd4eb8a000): JavaThread "Thread-7" [_thread_in_native, id=65539, stack(0x000000012c48d000,0x000000012c58d000)]
siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000000000000068
Registers:
RAX=0x0000000000000000, RBX=0x0000000000000000, RCX=0x00007fdd4e227ae0, RDX=0x3ff0000000000000
RSP=0x000000012c58bf40, RBP=0x000000012c58bfc0, RSI=0x0000000000000000, RDI=0x00007fff8b281450
R8 =0x0000000000000040, R9 =0x000000012c58be00, R10=0x00007fdd4d85a620, R11=0x0000000000000000
R12=0x0000000000000000, R13=0x00007fdd4cad4140, R14=0x0000000000000000, R15=0x0000000000000009
RIP=0x000000012c91e56b, EFLAGS=0x0000000000010246, ERR=0x0000000000000006
TRAPNO=0x000000000000000e
Top of Stack: (sp=0x000000012c58bf40)
0x000000012c58bf40: 000000012c8983a0 000000012c58bf70
0x000000012c58bf50: 0000000a000ef220 4043f3df1c59536e
0x000000012c58bf60: 3fffec982d5bb8b0 0000000000000048
0x000000012c58bf70: 00000039646e6162 00007fdd4cad4140
0x000000012c58bf80: 00007fdd4bdeee40 bd00be269df6f643
0x000000012c58bf90: 0000000000000000 00007fff915c58b7
0x000000012c58bfa0: 00007fdd4bdeee40 00007fdd4bdeee40
0x000000012c58bfb0: 0000000000000000 0000000000000010
0x000000012c58bfc0: 000000012c58c080 000000012c81e9a7
0x000000012c58bfd0: 000000012c58c010 00007fdd4bdee7f0
0x000000012c58bfe0: 000000030a1b0a00 000000012c58c040
0x000000012c58bff0: 000000010a1ad000 000000012c58c040
0x000000012c58c000: 00007fdd4bdee7f8 00007fdd4e227ae0
0x000000012c58c010: 00007fdd4cad4140 00007fdd4e2296c0
0x000000012c58c020: 000000012c816090 0000010000000000
0x000000012c58c030: 00007fdd4bdeee48 000000012c816090
0x000000012c58c040: 00007fdd4cad4140 00007fdd4e2296c0
0x000000012c58c050: 000000012c897c0c 00007fdd4bfcbe10
0x000000012c58c060: 0000000000000002 00007fdd5182f760
0x000000012c58c070: 0000000000000000 0000000000000002
0x000000012c58c080: 000000012c58c160 000000012c805109
0x000000012c58c090: 005a4303005a4200 00007fdd4bfcbe00
0x000000012c58c0a0: 0000000000000000 0000000000000002
0x000000012c58c0b0: 000000012c58c0e0 000000012c79f06d
0x000000012c58c0c0: 0000000000000000 00007fdd4e155958
0x000000012c58c0d0: 000000000000001c 00007fdd5182f760
0x000000012c58c0e0: 000000012c58c110 000000012c819c7e
0x000000012c58c0f0: 000000000000001c 00007fdd4bfaed60
0x000000012c58c100: 000000000000001c 00007fdd5182f760
0x000000012c58c110: 000000012c58c160 000000012c7dce0e
0x000000012c58c120: 00007fdd4bfaed60 00007fdd5182f760
0x000000012c58c130: 00007fdd4bfaed60 00007fdd4bfcbe10
Instructions: (pc=0x000000012c91e56b)
0x000000012c91e54b: 01 00 00 f2 0f 10 45 a0 f2 0f 59 c2 f2 0f 11 45
0x000000012c91e55b: 98 45 85 f6 75 13 49 8b 85 f0 02 00 00 48 8b 00
0x000000012c91e56b: c7 40 68 01 00 00 00 eb 2f 45 39 f7 75 18 49 8b
0x000000012c91e57b: 85 f0 02 00 00 48 8b 55 a8 48 8b 04 10 c7 40 68
Register to memory mapping:
RAX=0x0000000000000000 is an unknown value
RBX=0x0000000000000000 is an unknown value
RCX=0x00007fdd4e227ae0 is an unknown value
RDX=0x3ff0000000000000 is an unknown value
RSP=0x000000012c58bf40 is pointing into the stack for thread: 0x00007fdd4eb8a000
RBP=0x000000012c58bfc0 is pointing into the stack for thread: 0x00007fdd4eb8a000
RSI=0x0000000000000000 is an unknown value
RDI=0x00007fff8b281450: _FE_DFL_DISABLE_SSE_DENORMS_ENV+0x13178 in /usr/lib/system/libsystem_m.dylib at 0x00007fff8b259000
R8 =0x0000000000000040 is an unknown value
R9 =0x000000012c58be00 is pointing into the stack for thread: 0x00007fdd4eb8a000
R10=0x00007fdd4d85a620 is an unknown value
R11=0x0000000000000000 is an unknown value
R12=0x0000000000000000 is an unknown value
R13=0x00007fdd4cad4140 is an unknown value
R14=0x0000000000000000 is an unknown value
R15=0x0000000000000009 is an unknown value
Stack: [0x000000012c48d000,0x000000012c58d000], sp=0x000000012c58bf40, free space=1019k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libgstplugins-lite.dylib+0x1156b] gst_iir_equalizer_compute_frequencies+0x285
C [libglib-2.0.0.dylib+0x829a7] g_type_create_instance+0x861
C [libglib-2.0.0.dylib+0x69109] g_object_constructor+0x23
C [libglib-2.0.0.dylib+0x698ab] g_object_newv+0x38e
C [libgstreamer-lite.dylib+0x1440c] gst_element_factory_create+0x97
C [libgstreamer-lite.dylib+0x14531] gst_element_factory_make+0x67
C [libjfxmedia.dylib+0xfd04] CGstPipelineFactory::CreateAudioBin(char const*, char const*, bool, GstElementContainer*, int*, _GstElement**)+0x1d6
C [libjfxmedia.dylib+0x1036b] CGstPipelineFactory::CreateAudioPipeline(_GstElement*, char const*, char const*, bool, CPipelineOptions*, CPipeline**)+0xb7
C [libjfxmedia.dylib+0x10adf] CGstPipelineFactory::CreatePlayerPipeline(CLocator*, CPipelineOptions*, CPipeline**)+0x251
C [libjfxmedia.dylib+0x1e9a] CMediaManager::CreatePlayer(CLocator*, CPipelineOptions*, CMedia**)+0xce
C [libjfxmedia.dylib+0x12510] Java_com_sun_media_jfxmediaimpl_platform_gstreamer_GSTMedia_gstInitNativeMedia+0x1f6
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia.gstInitNativeMedia(Lcom/sun/media/jfxmedia/locator/Locator;Ljava/lang/String;J[J)I+0
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia.init()V+20
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia.<init>(Lcom/sun/media/jfxmedia/locator/Locator;)V+17
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMediaPlayer.<init>(Lcom/sun/media/jfxmedia/locator/Locator;)V+6
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTPlatform.prerollMediaPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Ljava/lang/Object;+5
j com.sun.media.jfxmediaimpl.platform.PlatformManager.createMediaPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Lcom/sun/media/jfxmedia/MediaPlayer;+47
j com.sun.media.jfxmediaimpl.NativeMediaManager.getPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Lcom/sun/media/jfxmedia/MediaPlayer;+7
j com.sun.media.jfxmedia.MediaManager.getPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Lcom/sun/media/jfxmedia/MediaPlayer;+18
j com.sun.webpane.sg.prism.WCMediaPlayerImpl$CreateThread.run()V+94
v ~StubRoutines::call_stub
V [libjvm.dylib+0x2d68c8] JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x22a
V [libjvm.dylib+0x2d6ddf] JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x11b
V [libjvm.dylib+0x2d6f1c] JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Thread*)+0x4a
V [libjvm.dylib+0x325da2] thread_entry(JavaThread*, Thread*)+0xad
V [libjvm.dylib+0x4ef417] JavaThread::thread_main_inner()+0x9b
V [libjvm.dylib+0x4f0b1f] JavaThread::run()+0x1a3
V [libjvm.dylib+0x41aaa1] java_start(Thread*)+0xd5
C [libsystem_pthread.dylib+0x1899] _pthread_body+0x8a
C [libsystem_pthread.dylib+0x172a] _pthread_struct_init+0x0
C [libsystem_pthread.dylib+0x5fc9] thread_start+0xd
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia.gstInitNativeMedia(Lcom/sun/media/jfxmedia/locator/Locator;Ljava/lang/String;J[J)I+0
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia.init()V+20
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia.<init>(Lcom/sun/media/jfxmedia/locator/Locator;)V+17
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMediaPlayer.<init>(Lcom/sun/media/jfxmedia/locator/Locator;)V+6
j com.sun.media.jfxmediaimpl.platform.gstreamer.GSTPlatform.prerollMediaPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Ljava/lang/Object;+5
j com.sun.media.jfxmediaimpl.platform.PlatformManager.createMediaPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Lcom/sun/media/jfxmedia/MediaPlayer;+47
j com.sun.media.jfxmediaimpl.NativeMediaManager.getPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Lcom/sun/media/jfxmedia/MediaPlayer;+7
j com.sun.media.jfxmedia.MediaManager.getPlayer(Lcom/sun/media/jfxmedia/locator/Locator;)Lcom/sun/media/jfxmedia/MediaPlayer;+18
j com.sun.webpane.sg.prism.WCMediaPlayerImpl$CreateThread.run()V+94
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x00007fdd4c0b8800 JavaThread "Thread-9" daemon [_thread_blocked, id=66819, stack(0x000000012cafd000,0x000000012cbfd000)]
0x00007fdd4d281800 JavaThread "Thread-8" daemon [_thread_blocked, id=66051, stack(0x000000012c977000,0x000000012ca77000)]
=>0x00007fdd4eb8a000 JavaThread "Thread-7" [_thread_in_native, id=65539, stack(0x000000012c48d000,0x000000012c58d000)]
0x00007fdd51833800 JavaThread "Thread-6" [_thread_in_native, id=65027, stack(0x000000012c38a000,0x000000012c48a000)]
0x00007fdd4da8f000 JavaThread "URL-Loader-8" daemon [_thread_blocked, id=64515, stack(0x000000012c287000,0x000000012c387000)]
0x00007fdd4d27c800 JavaThread "URL-Loader-7" daemon [_thread_blocked, id=64003, stack(0x000000012c184000,0x000000012c284000)]
0x00007fdd4d271000 JavaThread "URL-Loader-6" daemon [_thread_blocked, id=63491, stack(0x000000012c081000,0x000000012c181000)]
0x00007fdd4d018800 JavaThread "URL-Loader-5" daemon [_thread_blocked, id=62979, stack(0x000000012aa90000,0x000000012ab90000)]
0x00007fdd4d865000 JavaThread "URL-Loader-4" daemon [_thread_blocked, id=62467, stack(0x000000012a98d000,0x000000012aa8d000)]
0x00007fdd4ea13800 JavaThread "URL-Loader-3" daemon [_thread_blocked, id=61955, stack(0x000000012a88a000,0x000000012a98a000)]
0x00007fdd4ea10000 JavaThread "URL-Loader-2" daemon [_thread_blocked, id=61447, stack(0x00000001274e6000,0x00000001275e6000)]
0x00007fdd4da0d800 JavaThread "URL-Loader-1" daemon [_thread_blocked, id=60675, stack(0x0000000126ba5000,0x0000000126ca5000)]
0x00007fdd4d1f6000 JavaThread "Disposer" daemon [_thread_blocked, id=59915, stack(0x0000000126947000,0x0000000126a47000)]
0x00007fdd4d08a800 JavaThread "Prism Font Disposer" daemon [_thread_blocked, id=49679, stack(0x0000000120602000,0x0000000120702000)]
0x00007fdd4d094800 JavaThread "Thread-4" daemon [_thread_in_native, id=35843, stack(0x000000011eede000,0x000000011ef5e000)]
0x00007fdd4d890000 JavaThread "JavaFX Application Thread" [_thread_in_Java, id=1287, stack(0x00007fff559ec000,0x00007fff55a6c000)]
0x00007fdd4e8ce800 JavaThread "Thread-2" daemon [_thread_blocked, id=28419, stack(0x000000011c7c9000,0x000000011c8c9000)]
0x00007fdd4f827800 JavaThread "Disposer" daemon [_thread_blocked, id=27907, stack(0x000000011c663000,0x000000011c763000)]
0x00007fdd4d886800 JavaThread "QuantumRenderer-0" daemon [_thread_blocked, id=22787, stack(0x000000011ba9c000,0x000000011bb9c000)]
0x00007fdd4e805000 JavaThread "JavaFX-Launcher" [_thread_blocked, id=22275, stack(0x000000011b92c000,0x000000011ba2c000)]
0x00007fdd4d855800 JavaThread "Service Thread" daemon [_thread_blocked, id=21251, stack(0x000000011b670000,0x000000011b770000)]
0x00007fdd4d852800 JavaThread "C2 CompilerThread1" daemon [_thread_in_native, id=20739, stack(0x000000011b56d000,0x000000011b66d000)]
0x00007fdd4c818000 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=20227, stack(0x000000011b46a000,0x000000011b56a000)]
0x00007fdd4c800800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=19715, stack(0x000000011b367000,0x000000011b467000)]
0x00007fdd4c805000 JavaThread "Finalizer" daemon [_thread_blocked, id=14595, stack(0x000000011b11b000,0x000000011b21b000)]
0x00007fdd4c00b800 JavaThread "Reference Handler" daemon [_thread_blocked, id=14083, stack(0x000000011b018000,0x000000011b118000)]
0x00007fdd4d800000 JavaThread "main" [_thread_blocked, id=6403, stack(0x000000010a2a9000,0x000000010a3a9000)]
Other Threads:
0x00007fdd4e804800 VMThread [stack: 0x000000011af15000,0x000000011b015000] [id=13571]
0x00007fdd4e806000 WatcherThread [stack: 0x000000011b773000,0x000000011b873000] [id=21763]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
Heap
PSYoungGen total 76800K, used 20119K [0x00000007aaa80000, 0x00000007b0000000, 0x0000000800000000)
eden space 66048K, 19% used [0x00000007aaa80000,0x00000007ab6dfd58,0x00000007aeb00000)
from space 10752K, 69% used [0x00000007aeb00000,0x00000007af246120,0x00000007af580000)
to space 10752K, 0% used [0x00000007af580000,0x00000007af580000,0x00000007b0000000)
ParOldGen total 174592K, used 72K [0x0000000700000000, 0x000000070aa80000, 0x00000007aaa80000)
object space 174592K, 0% used [0x0000000700000000,0x0000000700012010,0x000000070aa80000)
PSPermGen total 21504K, used 18312K [0x00000006fae00000, 0x00000006fc300000, 0x0000000700000000)
object space 21504K, 85% used [0x00000006fae00000,0x00000006fbfe2118,0x00000006fc300000)
Card table byte_map: [0x000000010ef12000,0x000000010f73c000] byte_map_base: 0x000000010b73b000
Polling page: 0x000000010a3e8000
Code Cache [0x000000010be52000, 0x000000010c0c2000, 0x000000010ee52000)
total_blobs=879 nmethods=282 adapters=551 free_code_cache=47799Kb largest_free_block=48760384
Compilation events (10 events):
Event: 5.513 Thread 0x00007fdd4d852800 nmethod 295 0x000000010bfbb1d0 code [0x000000010bfbb320, 0x000000010bfbb598]
Event: 5.513 Thread 0x00007fdd4d852800 296 s sun.misc.PerfCounter::get (9 bytes)
Event: 5.514 Thread 0x00007fdd4d852800 nmethod 296 0x000000010bf23b90 code [0x000000010bf23ce0, 0x000000010bf23f38]
Event: 5.514 Thread 0x00007fdd4d852800 297 java.nio.DirectLongBufferU::get (16 bytes)
Event: 5.515 Thread 0x00007fdd4d852800 nmethod 297 0x000000010beeeed0 code [0x000000010beef000, 0x000000010beef098]
Event: 5.515 Thread 0x00007fdd4d852800 299 java.nio.DirectLongBufferU::put (18 bytes)
Event: 5.515 Thread 0x00007fdd4d852800 nmethod 299 0x000000010bf272d0 code [0x000000010bf27400, 0x000000010bf27498]
Event: 5.515 Thread 0x00007fdd4d852800 300 java.security.ProtectionDomain::getCodeSource (5 bytes)
Event: 5.515 Thread 0x00007fdd4d852800 nmethod 300 0x000000010bf27050 code [0x000000010bf27180, 0x000000010bf271f8]
Event: 5.518 Thread 0x00007fdd4c818000 nmethod 292 0x000000010bf1d090 code [0x000000010bf1d1e0, 0x000000010bf1d798]
GC Heap History (2 events):
Event: 5.192 GC heap before
{Heap before GC invocations=1 (full 0):
PSYoungGen total 76800K, used 66048K [0x00000007aaa80000, 0x00000007b0000000, 0x0000000800000000)
eden space 66048K, 100% used [0x00000007aaa80000,0x00000007aeb00000,0x00000007aeb00000)
from space 10752K, 0% used [0x00000007af580000,0x00000007af580000,0x00000007b0000000)
to space 10752K, 0% used [0x00000007aeb00000,0x00000007aeb00000,0x00000007af580000)
ParOldGen total 174592K, used 0K [0x0000000700000000, 0x000000070aa80000, 0x00000007aaa80000)
object space 174592K, 0% used [0x0000000700000000,0x0000000700000000,0x000000070aa80000)
PSPermGen total 21504K, used 16526K [0x00000006fae00000, 0x00000006fc300000, 0x0000000700000000)
object space 21504K, 76% used [0x00000006fae00000,0x00000006fbe239f0,0x00000006fc300000)
Event: 5.201 GC heap after
Heap after GC invocations=1 (full 0):
PSYoungGen total 76800K, used 7448K [0x00000007aaa80000, 0x00000007b0000000, 0x0000000800000000)
eden space 66048K, 0% used [0x00000007aaa80000,0x00000007aaa80000,0x00000007aeb00000)
from space 10752K, 69% used [0x00000007aeb00000,0x00000007af246120,0x00000007af580000)
to space 10752K, 0% used [0x00000007af580000,0x00000007af580000,0x00000007b0000000)
ParOldGen total 174592K, used 72K [0x0000000700000000, 0x000000070aa80000, 0x00000007aaa80000)
object space 174592K, 0% used [0x0000000700000000,0x0000000700012010,0x000000070aa80000)
PSPermGen total 21504K, used 16526K [0x00000006fae00000, 0x00000006fc300000, 0x0000000700000000)
object space 21504K, 76% used [0x00000006fae00000,0x00000006fbe239f0,0x00000006fc300000)
}
Deoptimization events (10 events):
Event: 5.209 Thread 0x00007fdd4d890000 Uncommon trap: reason=bimorphic action=maybe_recompile pc=0x000000010bf4f0e0 method=java.util.HashMap.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @ 83
Event: 5.209 Thread 0x00007fdd4d890000 Uncommon trap: reason=bimorphic action=maybe_recompile pc=0x000000010bf4f0e0 method=java.util.HashMap.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @ 83
Event: 5.209 Thread 0x00007fdd4d890000 Uncommon trap: reason=unreached action=reinterpret pc=0x000000010bec8bb0 method=java.lang.AbstractStringBuilder.append(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder; @ 1
Event: 5.215 Thread 0x00007fdd4d890000 Uncommon trap: reason=null_check action=make_not_entrant pc=0x000000010bfb4a80 method=java.util.LinkedHashMap.get(Ljava/lang/Object;)Ljava/lang/Object; @ 5
Event: 5.237 Thread 0x00007fdd4da0d800 Uncommon trap: reason=bimorphic action=maybe_recompile pc=0x000000010bf1bfb8 method=java.util.Collections$UnmodifiableCollection.size()I @ 4
Event: 5.358 Thread 0x00007fdd4d890000 Uncommon trap: reason=unloaded action=reinterpret pc=0x000000010bed2890 method=java.lang.CharacterData.of(I)Ljava/lang/CharacterData; @ 116
Event: 5.391 Thread 0x00007fdd4d890000 Uncommon trap: reason=unloaded action=reinterpret pc=0x000000010bfc1e1c method=java.lang.CharacterData.of(I)Ljava/lang/CharacterData; @ 96
Event: 5.505 Thread 0x00007fdd4d890000 Uncommon trap: reason=predicate action=maybe_recompile pc=0x000000010bfc74c0 method=java.util.ArrayList.indexOf(Ljava/lang/Object;)I @ 44
Event: 5.514 Thread 0x00007fdd4eb8a000 Uncommon trap: reason=unreached action=reinterpret pc=0x000000010bef27d8 method=java.net.URI.decode(Ljava/lang/String;)Ljava/lang/String; @ 1
Event: 5.514 Thread 0x00007fdd51833800 Uncommon trap: reason=unreached action=reinterpret pc=0x000000010bef27d8 method=java.net.URI.decode(Ljava/lang/String;)Ljava/lang/String; @ 1
Internal exceptions (10 events):
Event: 5.509 Thread 0x00007fdd51833800 Threw 0x00000007ab55de58 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.510 Thread 0x00007fdd51833800 Threw 0x00000007ab68d428 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.510 Thread 0x00007fdd51833800 Threw 0x00000007ab6902a0 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.512 Thread 0x00007fdd51833800 Threw 0x00000007ab693340 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.512 Thread 0x00007fdd51833800 Threw 0x00000007ab698060 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.513 Thread 0x00007fdd51833800 Threw 0x00000007ab69d178 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.513 Thread 0x00007fdd51833800 Threw 0x00000007ab6a4920 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.513 Thread 0x00007fdd51833800 Threw 0x00000007ab6a8918 at /HUDSON/workspace/jdk7u40-2-build-macosx-amd64-product/jdk7u40/hotspot/src/share/vm/prims/jvm.cpp:1244
Event: 5.514 Thread 0x00007fdd4eb8a000 Implicit null exception at 0x000000010bef0874 to 0x000000010bef27c9
Event: 5.514 Thread 0x00007fdd51833800 Implicit null exception at 0x000000010bef0874 to 0x000000010bef27c9
Events (10 events):
Event: 5.516 loading class 0x00007fdd4f9532c0
Event: 5.516 loading class 0x00007fdd4f9532c0 done
Event: 5.516 loading class 0x00007fdd4f9532f0
Event: 5.516 loading class 0x00007fdd4f953750
Event: 5.516 loading class 0x00007fdd4f954cd0
Event: 5.516 loading class 0x00007fdd4f954cd0 done
Event: 5.516 loading class 0x00007fdd4f953750 done
Event: 5.516 loading class 0x00007fdd4f9532f0 done
Event: 5.516 Executing VM operation: RevokeBias
Event: 5.516 Executing VM operation: RevokeBias done
Dynamic libraries:
0x000000000ae1a000 /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
0x000000000ae1a000 /System/Library/Frameworks/Security.framework/Versions/A/Security
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
0x000000000ae1a000 /usr/lib/libz.1.dylib
0x000000000ae1a000 /usr/lib/libSystem.B.dylib
0x000000000ae1a000 /usr/lib/libobjc.A.dylib
0x000000000ae1a000 /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
0x000000000ae1a000 /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
0x000000000ae1a000 /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
0x000000000ae1a000 /System/Library/Frameworks/CoreData.framework/Versions/A/CoreData
0x000000000ae1a000 /System/Library/PrivateFrameworks/RemoteViewServices.framework/Versions/A/RemoteViewServices
0x000000000ae1a000 /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox
0x000000000ae1a000 /System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit
0x000000000ae1a000 /System/Library/PrivateFrameworks/DataDetectorsCore.framework/Versions/A/DataDetectorsCore
0x000000000ae1a000 /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox
0x000000000ae1a000 /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SpeechRecognition.framework/Versions/A/SpeechRecognition
0x000000000ae1a000 /usr/lib/libauto.dylib
0x000000000ae1a000 /usr/lib/libicucore.A.dylib
0x000000000ae1a000 /usr/lib/libxml2.2.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/CoreUI.framework/Versions/A/CoreUI
0x000000000ae1a000 /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio
0x000000000ae1a000 /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration
0x000000000ae1a000 /usr/lib/liblangid.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/A/MultitouchSupport
0x000000000ae1a000 /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
0x000000000ae1a000 /usr/lib/libDiagnosticMessagesClient.dylib
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
0x000000000ae1a000 /System/Library/PrivateFrameworks/PerformanceAnalysis.framework/Versions/A/PerformanceAnalysis
0x000000000ae1a000 /System/Library/PrivateFrameworks/GenerationalStorage.framework/Versions/A/GenerationalStorage
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL
0x000000000ae1a000 /System/Library/PrivateFrameworks/Sharing.framework/Versions/A/Sharing
0x000000000ae1a000 /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
0x000000000ae1a000 /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText
0x000000000ae1a000 /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics
0x000000000ae1a000 /System/Library/PrivateFrameworks/Backup.framework/Versions/A/Backup
0x000000000ae1a000 /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork
0x000000000ae1a000 /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration
0x000000000ae1a000 /usr/lib/libCRFSuite.dylib
0x000000000ae1a000 /usr/lib/libc++.1.dylib
0x000000000ae1a000 /usr/lib/libc++abi.dylib
0x000000000ae1a000 /usr/lib/system/libcache.dylib
0x000000000ae1a000 /usr/lib/system/libcommonCrypto.dylib
0x000000000ae1a000 /usr/lib/system/libcompiler_rt.dylib
0x000000000ae1a000 /usr/lib/system/libcopyfile.dylib
0x000000000ae1a000 /usr/lib/system/libcorecrypto.dylib
0x000000000ae1a000 /usr/lib/system/libdispatch.dylib
0x000000000ae1a000 /usr/lib/system/libdyld.dylib
0x000000000ae1a000 /usr/lib/system/libkeymgr.dylib
0x000000000ae1a000 /usr/lib/system/liblaunch.dylib
0x000000000ae1a000 /usr/lib/system/libmacho.dylib
0x000000000ae1a000 /usr/lib/system/libquarantine.dylib
0x000000000ae1a000 /usr/lib/system/libremovefile.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_asl.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_blocks.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_c.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_configuration.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_dnssd.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_info.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_kernel.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_m.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_malloc.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_network.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_notify.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_platform.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_pthread.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_sandbox.dylib
0x000000000ae1a000 /usr/lib/system/libsystem_stats.dylib
0x000000000ae1a000 /usr/lib/system/libunc.dylib
0x000000000ae1a000 /usr/lib/system/libunwind.dylib
0x000000000ae1a000 /usr/lib/system/libxpc.dylib
0x000000000ae1a000 /usr/lib/libbsm.0.dylib
0x000000000ae1a000 /usr/lib/libsqlite3.dylib
0x000000000ae1a000 /usr/lib/libxar.1.dylib
0x000000000ae1a000 /usr/lib/libpam.2.dylib
0x000000000ae1a000 /usr/lib/libOpenScriptingUtil.dylib
0x000000000ae1a000 /usr/lib/libbz2.1.0.dylib
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices
0x000000000ae1a000 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices
0x000000000ae1a000 /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS
0x000000000ae1a000 /usr/lib/system/libkxld.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/NetAuth.framework/Versions/A/NetAuth
0x000000000ae1a000 /System/Library/PrivateFrameworks/TCC.framework/Versions/A/TCC
0x000000000ae1a000 /System/Library/Frameworks/OpenDirectory.framework/Versions/A/Frameworks/CFOpenDirectory.framework/Versions/A/CFOpenDirectory
0x000000000ae1a000 /System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement
0x000000000ae1a000 /usr/lib/libxslt.1.dylib
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Ink.framework/Versions/A/Ink
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSync.framework/Versions/A/ColorSync
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LangAnalysis.framework/Versions/A/LangAnalysis
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis
0x000000000ae1a000 /System/Library/Frameworks/IOSurface.framework/Versions/A/IOSurface
0x000000000ae1a000 /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate
0x000000000ae1a000 /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vImage.framework/Versions/A/vImage
0x000000000ae1a000 /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/vecLib
0x000000000ae1a000 /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib
0x000000000ae1a000 /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvMisc.dylib
0x000000000ae1a000 /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib
0x000000000ae1a000 /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontParser.dylib
0x000000000ae1a000 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontRegistry.dylib
0x000000000ae1a000 /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib
0x000000000ae1a000 /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib
0x000000000ae1a000 /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libPng.dylib
0x000000000ae1a000 /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libGIF.dylib
0x000000000ae1a000 /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJP2.dylib
0x000000000ae1a000 /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libRadiance.dylib
0x000000000ae1a000 /usr/lib/libcups.2.dylib
0x000000000ae1a000 /System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos
0x000000000ae1a000 /System/Library/Frameworks/GSS.framework/Versions/A/GSS
0x000000000ae1a000 /usr/lib/libresolv.9.dylib
0x000000000ae1a000 /usr/lib/libiconv.2.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/Heimdal.framework/Versions/A/Heimdal
0x000000000ae1a000 /System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent
0x000000000ae1a000 /usr/lib/libheimdal-asn1.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenDirectory.framework/Versions/A/OpenDirectory
0x000000000ae1a000 /System/Library/PrivateFrameworks/CommonAuth.framework/Versions/A/CommonAuth
0x000000000ae1a000 /System/Library/Frameworks/SecurityFoundation.framework/Versions/A/SecurityFoundation
0x000000000ae1a000 /System/Library/PrivateFrameworks/Bom.framework/Versions/A/Bom
0x000000000ae1a000 /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo
0x000000000ae1a000 /System/Library/Frameworks/QuartzCore.framework/Versions/A/Frameworks/CoreImage.framework/Versions/A/CoreImage
0x000000000ae1a000 /System/Library/Frameworks/QuartzCore.framework/Versions/A/Frameworks/ScalableUserInterface.framework/Versions/A/ScalableUserInterface
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGFXShared.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLImage.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCVMSPluginSupport.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCoreVMClient.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/FaceCore.framework/Versions/A/FaceCore
0x000000000ae1a000 /System/Library/PrivateFrameworks/CrashReporterSupport.framework/Versions/A/CrashReporterSupport
0x000000000ae1a000 /System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL
0x000000000ae1a000 /System/Library/PrivateFrameworks/AppleFSCompression.framework/Versions/A/AppleFSCompression
0x000000000ae1a000 /System/Library/PrivateFrameworks/Ubiquity.framework/Versions/A/Ubiquity
0x000000000ae1a000 /System/Library/PrivateFrameworks/IconServices.framework/Versions/A/IconServices
0x000000000ae1a000 /System/Library/PrivateFrameworks/ChunkingLibrary.framework/Versions/A/ChunkingLibrary
0x000000000ae1a000 /System/Library/PrivateFrameworks/CoreSymbolication.framework/Versions/A/CoreSymbolication
0x000000000ae1a000 /System/Library/PrivateFrameworks/Symbolication.framework/Versions/A/Symbolication
0x000000000ae1a000 /System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols
0x000000010b400000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/server/libjvm.dylib
0x000000000ae1a000 /usr/lib/libstdc++.6.dylib
0x000000010a3ab000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libverify.dylib
0x000000010a3b8000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libjava.dylib
0x000000010a3f2000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libzip.dylib
0x000000011b21d000 /System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport
0x000000011b235000 /System/Library/Frameworks/JavaVM.framework/Versions/A/Frameworks/JavaNativeFoundation.framework/Versions/A/JavaNativeFoundation
0x000000011b249000 /System/Library/Frameworks/JavaVM.framework/Versions/A/JavaVM
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
0x000000011b255000 /System/Library/PrivateFrameworks/JavaLaunching.framework/Versions/A/JavaLaunching
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CommonPanels.framework/Versions/A/CommonPanels
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Help.framework/Versions/A/Help
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Print.framework/Versions/A/Print
0x000000000ae1a000 /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SecurityHI.framework/Versions/A/SecurityHI
0x000000011bb9e000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libprism-es2.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLProgrammability.dylib
0x0000000000000000 /System/Library/Extensions/AppleIntelHD4000GraphicsGLDriver.bundle/Contents/MacOS/AppleIntelHD4000GraphicsGLDriver
0x000000000ae1a000 /System/Library/PrivateFrameworks/IOAccelerator.framework/Versions/A/IOAccelerator
0x000000000ae1a000 /System/Library/PrivateFrameworks/GPUSupport.framework/Versions/A/Libraries/libGPUSupportMercury.dylib
0x0000000000000000 /System/Library/Extensions/GeForceGLDriver.bundle/Contents/MacOS/GeForceGLDriver
0x000000000ae1a000 /System/Library/Extensions/GeForceGLDriver.bundle/Contents/MacOS/libclh.dylib
0x000000000ae1a000 /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLRendererFloat.bundle/GLRendererFloat
0x000000000ae1a000 /System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries/libcldcpuengine.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/DiskImages.framework/Versions/A/DiskImages
0x000000000ae1a000 /System/Library/Frameworks/DiscRecording.framework/Versions/A/DiscRecording
0x000000000ae1a000 /usr/lib/libcsfde.dylib
0x000000000ae1a000 /usr/lib/libcurl.4.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/MediaKit.framework/Versions/A/MediaKit
0x000000000ae1a000 /usr/lib/libCoreStorage.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/EFILogin.framework/Versions/A/EFILogin
0x000000000ae1a000 /usr/lib/libutil.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/AOSNotification.framework/Versions/A/AOSNotification
0x000000000ae1a000 /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP
0x000000000ae1a000 /usr/lib/libsasl2.2.dylib
0x000000000ae1a000 /usr/lib/libcrypto.0.9.8.dylib
0x000000000ae1a000 /usr/lib/libssl.0.9.8.dylib
0x000000011c765000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libglass.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/CoreServicesInternal.framework/Versions/A/CoreServicesInternal
0x000000000ae1a000 /System/Library/PrivateFrameworks/Librarian.framework/Versions/A/Librarian
0x000000000ae1a000 /System/Library/CoreServices/RawCamera.bundle/Contents/MacOS/RawCamera
0x000000000ae1a000 /System/Library/Frameworks/CoreGraphics.framework/Versions/A/Resources/libCGCMS.A.dylib
0x000000000ae1a000 /System/Library/Frameworks/CoreGraphics.framework/Versions/A/Resources/libRIP.A.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/FamilyControls.framework/Versions/A/FamilyControls
0x000000000ae1a000 /System/Library/PrivateFrameworks/CommerceKit.framework/Versions/A/Frameworks/CommerceCore.framework/Versions/A/CommerceCore
0x000000000ae1a000 /System/Library/PrivateFrameworks/SystemAdministration.framework/Versions/A/SystemAdministration
0x000000000ae1a000 /System/Library/Frameworks/DirectoryService.framework/Versions/A/DirectoryService
0x000000000ae1a000 /System/Library/PrivateFrameworks/LoginUIKit.framework/Versions/A/Frameworks/LoginUICore.framework/Versions/A/LoginUICore
0x000000000ae1a000 /usr/lib/libodfde.dylib
0x000000012027b000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libjavafx-font.dylib
0x000000000ae1a000 /System/Library/Frameworks/CoreGraphics.framework/Versions/A/Resources/libCGXType.A.dylib
0x000000011ba7f000 cl_kernels
0x0000000122ada000 /System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries/ImageFormats/unorm8_bgra.dylib
0x000000011ba92000 cl_kernels
0x000000011ba98000 cl_kernels
0x00000001200ec000 cl_kernels
0x0000000122d8b000 /System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries/ImageFormats/unorm8_argb.dylib
0x00000001284f3000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libjfxwebkit.dylib
0x00000001204f7000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libnio.dylib
0x000000012070e000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/./libnet.dylib
0x000000012c58f000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libjfxmedia.dylib
0x000000012c5ef000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib//libgstreamer-lite.dylib
0x000000012c79c000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib//libglib-2.0.0.dylib
0x000000000ae1a000 /System/Library/Frameworks/QTKit.framework/Versions/A/QTKit
0x000000000ae1a000 /System/Library/Frameworks/AVFoundation.framework/Versions/A/AVFoundation
0x000000000ae1a000 /System/Library/Frameworks/CoreMedia.framework/Versions/A/CoreMedia
0x000000000ae1a000 /System/Library/Frameworks/MediaToolbox.framework/Versions/A/MediaToolbox
0x000000000ae1a000 /System/Library/Frameworks/VideoToolbox.framework/Versions/A/VideoToolbox
0x000000000ae1a000 /System/Library/PrivateFrameworks/CoreMediaAuthoring.framework/Versions/A/CoreMediaAuthoring
0x000000000ae1a000 /System/Library/Frameworks/CoreMediaIO.framework/Versions/A/CoreMediaIO
0x000000000ae1a000 /System/Library/Frameworks/AVFoundation.framework/Versions/A/Resources/libAVFAudio.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/MediaControlSender.framework/Versions/A/MediaControlSender
0x000000000ae1a000 /System/Library/PrivateFrameworks/CoreAVCHD.framework/Versions/A/CoreAVCHD
0x000000000ae1a000 /System/Library/Frameworks/MediaAccessibility.framework/Versions/A/MediaAccessibility
0x000000000ae1a000 /System/Library/PrivateFrameworks/Mangrove.framework/Versions/A/Mangrove
0x000000000ae1a000 /System/Library/PrivateFrameworks/CoreAUC.framework/Versions/A/CoreAUC
0x000000000ae1a000 /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Apple80211
0x000000000ae1a000 /System/Library/PrivateFrameworks/AppleSRP.framework/Versions/A/AppleSRP
0x000000000ae1a000 /System/Library/PrivateFrameworks/CoreUtils.framework/Versions/A/CoreUtils
0x000000000ae1a000 /System/Library/Frameworks/CoreWLAN.framework/Versions/A/CoreWLAN
0x000000000ae1a000 /usr/lib/libpcap.A.dylib
0x000000000ae1a000 /System/Library/Frameworks/CoreWiFi.framework/Versions/A/CoreWiFi
0x000000000ae1a000 /System/Library/PrivateFrameworks/AppleVA.framework/Versions/A/AppleVA
0x000000000ae1a000 /System/Library/PrivateFrameworks/XPCService.framework/Versions/A/XPCService
0x000000000ae1a000 /System/Library/PrivateFrameworks/AppSandbox.framework/Versions/A/AppSandbox
0x000000000ae1a000 /usr/lib/libsandbox.1.dylib
0x000000000ae1a000 /System/Library/PrivateFrameworks/AppContainer.framework/Versions/A/AppContainer
0x000000000ae1a000 /System/Library/PrivateFrameworks/SecCodeWrapper.framework/Versions/A/SecCodeWrapper
0x000000000ae1a000 /usr/lib/libMatch.1.dylib
0x000000012c8cd000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/fxplugins.dylib
0x0000000120480000 /System/Library/Frameworks/VideoDecodeAcceleration.framework/Versions/A/VideoDecodeAcceleration
0x000000012c90d000 /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/libgstplugins-lite.dylib
VM Arguments:
java_command: org.badvision.outlaweditor.Application
Launcher Type: SUN_STANDARD
Environment Variables:
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home
PATH=/usr/bin:/bin:/usr/sbin:/sbin
LD_LIBRARY_PATH=/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/amd64:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/i386:
SHELL=/bin/bash
DISPLAY=/tmp/launch-c7yhD3/org.macosforge.xquartz:0
DYLD_LIBRARY_PATH=/Applications/NetBeans/NetBeans 7.4.app/Contents/Resources/NetBeans/webcommon/bin:
Signal Handlers:
SIGSEGV: [libjvm.dylib+0x524ce5], sa_mask[0]=0xfffefeff, sa_flags=0x00000043
SIGBUS: [libjvm.dylib+0x524ce5], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
SIGFPE: [libjvm.dylib+0x4182a6], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
SIGPIPE: [libjvm.dylib+0x4182a6], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
SIGXFSZ: [libjvm.dylib+0x4182a6], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
SIGILL: [libjvm.dylib+0x4182a6], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
SIGUSR1: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000002
SIGUSR2: [libjvm.dylib+0x417d98], sa_mask[0]=0x00000004, sa_flags=0x00000042
SIGHUP: [libjvm.dylib+0x416027], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
SIGINT: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000
SIGTERM: [libjvm.dylib+0x416027], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
SIGQUIT: [libjvm.dylib+0x416027], sa_mask[0]=0xfffefeff, sa_flags=0x00000042
--------------- S Y S T E M ---------------
OS:Bsduname:Darwin 13.1.0 Darwin Kernel Version 13.1.0: Thu Jan 16 19:40:37 PST 2014; root:xnu-2422.90.20~2/RELEASE_X86_64 x86_64
rlimit: STACK 8192k, CORE 0k, NPROC 709, NOFILE 10240, AS infinity
load average:2.71 2.58 2.43
CPU:total 8 (4 cores per cpu, 2 threads per core) family 6 model 58 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, aes, erms, ht, tsc, tscinvbit, tscinv
Memory: 4k page, physical 16777216k(4194304k free)
/proc/meminfo:
vm_info: Java HotSpot(TM) 64-Bit Server VM (24.0-b55) for bsd-amd64 JRE (1.7.0_40-b40), built on Aug 16 2013 11:52:39 by "java_re" with gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
time: Sun Mar 23 00:59:29 2014
elapsed time: 5 seconds

View File

@ -86,7 +86,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<version>4.11</version>
<scope>test</scope>
<type>jar</type>
</dependency>

View File

@ -54,11 +54,8 @@ public class Application extends javafx.application.Application {
throw new RuntimeException(exception);
}
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(final WindowEvent t) {
t.consume();
}
primaryStage.setOnCloseRequest((final WindowEvent t) -> {
t.consume();
});
primaryStage.show();
}

View File

@ -1,6 +1,6 @@
package org.badvision.outlaweditor;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import org.badvision.outlaweditor.data.DataObserver;
import org.badvision.outlaweditor.data.DataProducer;
import org.badvision.outlaweditor.data.xml.Script;
@ -28,7 +28,7 @@ public abstract class Editor<T, D> implements DataObserver<T> {
abstract public void showShiftUI();
abstract public void buildEditorUI(AnchorPane tileEditorAnchorPane);
abstract public void buildEditorUI(Pane targetPane);
abstract public void unregister();

View File

@ -54,6 +54,7 @@ public class FileUtils {
}
if (create) {
File file = f.showSaveDialog(Application.getPrimaryStage());
if (file == null) return null;
if (!file.getName().contains(".")) {
return new File(file.getParentFile(), file.getName() + "." + supportedExtensions[0].extension);
} else {

View File

@ -21,13 +21,13 @@ public abstract class ImageEditor extends Editor<Image, ImageEditor.DrawMode> {
abstract public void buildPatternSelector(Menu tilePatternMenu);
public abstract void scrollBy(int deltaX, int deltaY);
public abstract void togglePanZoom();
public abstract void zoomIn();
public abstract void zoomOut();
public abstract double getZoomScale();
public abstract void exportImage();

View File

@ -19,7 +19,7 @@ import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
@ -37,7 +37,7 @@ import org.badvision.outlaweditor.ui.ToolType;
*/
public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventHandler<MouseEvent> {
AnchorPane anchorPane;
Pane anchorPane;
Canvas drawCanvas;
private Tile currentTile;
int posX = 0;
@ -80,7 +80,7 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
}
@Override
public void buildEditorUI(AnchorPane tileEditorAnchorPane) {
public void buildEditorUI(Pane tileEditorAnchorPane) {
anchorPane = tileEditorAnchorPane;
initCanvas();
redraw();

View File

@ -7,7 +7,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
@ -46,7 +45,6 @@ public class MythosEditor {
public void show() {
primaryStage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/MythosScriptEditor.fxml"));
Map<String, String> properties = new HashMap<>();
properties.put(MythosScriptEditorController.ONLOAD_SCRIPT, generateLoadScript());
@ -61,22 +59,16 @@ public class MythosEditor {
throw new RuntimeException(exception);
}
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(final WindowEvent t) {
t.consume();
}
primaryStage.setOnCloseRequest((final WindowEvent t) -> {
t.consume();
});
primaryStage.show();
}
public void close() {
javafx.application.Platform.runLater(new Runnable() {
@Override
public void run() {
primaryStage.getScene().getRoot().setDisable(true);
primaryStage.close();
}
javafx.application.Platform.runLater(() -> {
primaryStage.getScene().getRoot().setDisable(true);
primaryStage.close();
});
}

View File

@ -8,14 +8,13 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.Menu;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import org.badvision.outlaweditor.Application;
@ -23,7 +22,6 @@ import org.badvision.outlaweditor.FileUtils;
import org.badvision.outlaweditor.ImageEditor;
import org.badvision.outlaweditor.Platform;
import org.badvision.outlaweditor.ui.UIAction;
import org.badvision.outlaweditor.data.DataObserver;
import org.badvision.outlaweditor.data.TileMap;
import org.badvision.outlaweditor.data.xml.Image;
import org.badvision.outlaweditor.data.xml.PlatformData;
@ -34,11 +32,11 @@ import org.badvision.outlaweditor.data.xml.PlatformData;
*/
public class AppleImageEditor extends ImageEditor implements EventHandler<MouseEvent> {
public int[] currentFillPattern = FillPattern.White.bytePattern;
public int[] currentFillPattern = FillPattern.White_PC.bytePattern;
public boolean hiBitMatters = true;
protected DrawMode currentDrawMode = DrawMode.Pencil1px;
protected WritableImage currentImage;
protected AnchorPane anchorPane;
protected Pane anchorPane;
protected ImageView screen;
protected int posX = 0;
protected int posY = 0;
@ -51,7 +49,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
}
@Override
public void buildEditorUI(AnchorPane editorAnchorPane) {
public void buildEditorUI(Pane editorAnchorPane) {
anchorPane = editorAnchorPane;
redraw();
screen = new ImageView(currentImage);
@ -65,11 +63,8 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
@Override
public void buildPatternSelector(Menu tilePatternMenu) {
FillPattern.buildMenu(tilePatternMenu, new DataObserver<FillPattern>() {
@Override
public void observedObjectChanged(FillPattern object) {
changeCurrentPattern(object);
}
FillPattern.buildMenu(tilePatternMenu, (FillPattern object) -> {
changeCurrentPattern(object);
});
}
@ -110,11 +105,8 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
public void redraw() {
System.out.println("Redraw " + getPlatform().name());
currentImage = getPlatform().imageRenderer.renderImage(currentImage, getImageData(), getWidth(), getHeight());
anchorPane.getChildren().get(1).setLayoutX((anchorPane.getWidth() - 30) / 2);
anchorPane.getChildren().get(2).setLayoutY((anchorPane.getHeight() - 30) / 2);
anchorPane.getChildren().get(3).setLayoutX((anchorPane.getWidth() - 30) / 2);
anchorPane.getChildren().get(4).setLayoutY((anchorPane.getHeight() - 30) / 2);
}
private byte[] imageData = null;
public byte[] getImageData() {
@ -143,23 +135,16 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
}
}
@Override
public void togglePanZoom() {
for (Node n : anchorPane.getChildren()) {
if (n == screen) {
continue;
}
n.setVisible(!n.isVisible());
}
public void setDataAndRedraw(byte[] data) {
setData(data);
redraw();
}
@Override
public void scrollBy(int deltaX, int deltaY) {
posX += deltaX * 10;
posY += deltaY * 10;
posX = Math.max(0, posX);
posY = Math.max(0, posY);
redraw();
public void togglePanZoom() {
anchorPane.getChildren().stream().filter((n) -> !(n == screen)).forEach((n) -> {
n.setVisible(!n.isVisible());
});
}
@Override
@ -180,26 +165,14 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
}
}
@Override
public double getZoomScale() {
return zoom;
}
private void zoom(double delta) {
double oldZoom = zoom;
zoom += delta;
zoom = Math.min(Math.max(0.15, zoom), 4.0);
// double left = mapEditorScroll.getHvalue();
// double top = mapEditorScroll.getVvalue();
//
// double pointerX = t.getX();
// double pointerY = t.getY();
//
double ratio = zoom / oldZoom;
//
// double newLeft = (left + pointerX) * ratio - pointerX;
// double newTop = (top + pointerY) * ratio - pointerY;
// Scale the image and move it so the upper-left corner is still in the right place.
screen.setScaleX(zoom);
screen.setScaleY(zoom);
screen.setTranslateX(getWidth()*7 * (zoom-1));
screen.setTranslateY(getHeight() * (zoom-1));
redraw();
}
@Override
@ -280,8 +253,8 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
private void startSelection(int x, int y) {
selectRect = new Rectangle(1, 1, Color.NAVY);
selectRect.setTranslateX(x * xScale * zoom);
selectRect.setTranslateY(y * yScale * zoom);
selectRect.setTranslateX(x * xScale);
selectRect.setTranslateY(y * yScale);
selectRect.setOpacity(0.5);
selectStartX = x;
selectStartY = y;
@ -293,10 +266,10 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
startSelection(x, y);
}
double minX = Math.min(selectStartX, x) * xScale * zoom;
double minY = Math.min(selectStartY, y) * yScale * zoom;
double maxX = Math.max(selectStartX, x) * xScale * zoom;
double maxY = Math.max(selectStartY, y) * yScale * zoom;
double minX = Math.min(selectStartX, x) * xScale;
double minY = Math.min(selectStartY, y) * yScale;
double maxX = Math.max(selectStartX, x) * xScale;
double maxY = Math.max(selectStartY, y) * yScale;
selectRect.setTranslateX(minX);
selectRect.setTranslateY(minY);
selectRect.setWidth(maxX - minX);
@ -393,9 +366,10 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
if (pasteAppContent((String) Clipboard.getSystemClipboard().getContent(DataFormat.PLAIN_TEXT))) {
return;
}
};
}
if (Clipboard.getSystemClipboard().hasContent(DataFormat.IMAGE)) {
javafx.scene.image.Image image = Clipboard.getSystemClipboard().getImage();
importImage(image);
}
}
@ -435,13 +409,9 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
}
private void importImage(javafx.scene.image.Image image) {
FloydSteinbergDither.floydSteinbergDither(image, getPlatform(), 0, 0, getWidth(), getHeight(), getImageData(), getWidth(), new FloydSteinbergDither.DitherCallback() {
@Override
public void ditherCompleted(byte[] data) {
setData(data);
redraw();
}
});
ImageDitherEngine ditherEngine = new ImageDitherEngine(getPlatform());
ditherEngine.setTargetCoordinates(0, 0);
UIAction.openImageConversionModal(image, ditherEngine, getWidth(), getHeight(), this::setDataAndRedraw);
}
private int calculateHiresOffset(int y) {
@ -466,11 +436,9 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
if (out == null) {
return;
}
try {
FileOutputStream outStream = new FileOutputStream(out);
try (FileOutputStream outStream = new FileOutputStream(out)) {
outStream.write(output);
outStream.flush();
outStream.close();
} catch (IOException ex) {
Logger.getLogger(AppleImageEditor.class.getName()).log(Level.SEVERE, null, ex);
}
@ -478,18 +446,11 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
@Override
public void resize(final int newWidth, final int newHeight) {
UIAction.confirm("Do you want to scale the image? If you select no, the image will be cropped as needed.",
new Runnable() {
@Override
public void run() {
rescale(newWidth, newHeight);
}
}, new Runnable() {
@Override
public void run() {
crop(newWidth, newHeight);
}
});
UIAction.confirm("Do you want to scale the image? If you select no, the image will be cropped as needed.", () -> {
rescale(newWidth, newHeight);
}, () -> {
crop(newWidth, newHeight);
});
}
/**

View File

@ -6,7 +6,7 @@ import javafx.scene.control.Menu;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
@ -34,7 +34,7 @@ public class AppleTileEditor extends TileEditor {
}
@Override
public void buildEditorUI(AnchorPane tileEditorAnchorPane) {
public void buildEditorUI(Pane tileEditorAnchorPane) {
grid = new Rectangle[14][16];
gridGroup = new Group();
for (int y = 0; y < 16; y++) {
@ -42,17 +42,11 @@ public class AppleTileEditor extends TileEditor {
final int xx = x;
final int yy = y;
Rectangle rect = new Rectangle(zoom * x + 5, zoom * y + 5, zoom - 2, zoom - 2);
rect.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
performDragAction((int) (t.getX() / zoom), (int) (t.getY() / zoom));
}
rect.setOnMouseDragged((MouseEvent t) -> {
performDragAction((int) (t.getX() / zoom), (int) (t.getY() / zoom));
});
rect.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
handleMouse(t, xx, yy);
}
rect.setOnMousePressed((MouseEvent t) -> {
handleMouse(t, xx, yy);
});
grid[x][y] = rect;
gridGroup.getChildren().add(rect);
@ -146,11 +140,8 @@ public class AppleTileEditor extends TileEditor {
@Override
public void buildPatternSelector(Menu tilePatternMenu) {
FillPattern.buildMenu(tilePatternMenu, new DataObserver<FillPattern>() {
@Override
public void observedObjectChanged(FillPattern object) {
changeCurrentPattern(object);
}
FillPattern.buildMenu(tilePatternMenu, (FillPattern object) -> {
changeCurrentPattern(object);
});
}

View File

@ -95,8 +95,12 @@ public enum FillPattern {
LightOrange2(true, 4, true,
"-+++-+++-+++-+++-+++-+++-+++",
"++-+++-+++-+++-+++-+++-+++-+"),
Black(false, 1, false, "-------"),
White(false, 1, false, "+++++++"),
Black_PC(false, 1, false, "-------"),
Black_Lo(true, 1, false, "-------"),
Black_Hi(true, 1, true, "-------"),
White_PC(false, 1, false, "+++++++"),
White_Lo(true, 1, false, "+++++++"),
White_Hi(true, 1, true, "+++++++"),
BW1(false, 4, false,
"++--++--++--++--++--++--++--",
"--++--++--++--++--++--++--++"

View File

@ -1,479 +0,0 @@
package org.badvision.outlaweditor.apple;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import static org.badvision.outlaweditor.apple.AppleNTSCGraphics.hgrToDhgr;
/* Copyright (c) 2013 the authors listed at the following URL, and/or
the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Floyd-Steinberg_dithering_(Java)?action=history&offset=20080201121723
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Retrieved from: http://en.literateprograms.org/Floyd-Steinberg_dithering_(Java)?oldid=12476
* Original code by Spoon! (Feb 2008)
* Modified and adapted to work with Apple Game Server by Brendan Robert (2013)
* Some of the original code of this class was migrated over to the Palette class which already manages colors in AGS.
*/
public class FloydSteinbergDither {
static final int totalPasses = 1;
static final int nonErrorPasses = 1;
public static interface DitherCallback {
public void ditherCompleted(byte[] data);
}
public static void floydSteinbergDither(
Image img,
final org.badvision.outlaweditor.Platform platform,
final int startX,
final int startY,
final int width,
final int height,
final byte[] screen,
final int bufferWidth,
final DitherCallback callback) {
final AppleImageRenderer renderer = (AppleImageRenderer) platform.imageRenderer;
final int errorWindow = 6;
final int overlap = 2;
final int pixelShift = -2;
int byteRenderWidth = platform == org.badvision.outlaweditor.Platform.AppleII_DHGR ? 7 : 14;
final WritableImage source = getScaledImage(img, width * byteRenderWidth, height);
AnchorPane pane = new AnchorPane();
Scene s = new Scene(pane);
final ImageView previewImage = new ImageView(source);
previewImage.setLayoutX(0);
previewImage.setLayoutY(0);
pane.getChildren().add(previewImage);
final Text status = new Text("Status");
status.setLayoutX(100);
status.setLayoutY(40);
status.setFont(Font.font("Arial", 18));
status.setStroke(Color.BLACK);
status.setEffect(new DropShadow(10.0, 0, 0, Color.WHITE));
pane.getChildren().add(status);
Stage progress = new Stage();
progress.setScene(s);
progress.show();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
final WritableImage keepScaled = new WritableImage(source.getPixelReader(), 560, 192);
WritableImage tmpScaled = new WritableImage(source.getPixelReader(), 560, 192);
for (int i = 0; i < screen.length; i++) {
screen[i] = (byte) Math.max(255, Math.random() * 256.0);
}
// Platform.runLater(new Runnable() {
// @Override
// public void run() {
// previewImage.setCache(false);
// previewImage.setImage(keepScaled);
// }
// });
// try {
// while (previewImage.getImage() != keepScaled) {
// Thread.sleep(10);
// }
// } catch (InterruptedException ex) {
// Logger.getLogger(FloydSteinbergDither.class.getName()).log(Level.SEVERE, null, ex);
// }
int[] scanline = new int[3];
List<Integer> pixels = new ArrayList<>();
for (int pass = 0; pass < totalPasses; pass++) {
keepScaled.getPixelWriter().setPixels(0, 0, 560, 192, source.getPixelReader(), 0, 0);
tmpScaled.getPixelWriter().setPixels(0, 0, 560, 192, source.getPixelReader(), 0, 0);
final String statusText = "Pass: " + (pass + 1) + " of " + totalPasses;
Platform.runLater(new Runnable() {
@Override
public void run() {
status.setText(statusText);
}
});
System.out.println("Image type: " + platform.name());
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x += 2) {
Thread.yield();
switch (platform) {
case AppleII:
hiresDither(screen, y, x, scanline, pixels, tmpScaled, pass, keepScaled);
break;
case AppleII_DHGR:
doubleHiresDither(screen, y, x, scanline, pixels, tmpScaled, pass, keepScaled);
break;
}
}
}
Platform.runLater(new Runnable() {
@Override
public void run() {
callback.ditherCompleted(screen);
}
});
}
status.setText("Complete!");
}
void hiresDither(final byte[] screen, int y, int x, int[] scanline, List<Integer> pixels, WritableImage tmpScaled, int pass, final WritableImage keepScaled) {
int bb1 = screen[(y + startY) * bufferWidth + startX + x] & 255;
int bb2 = screen[(y + startY) * bufferWidth + startX + x + 1] & 255;
int next = bb2 & 127; // Preserve hi-bit so last pixel stays solid, it is a very minor detail
int prev = 0;
if ((x + startX) > 0) {
prev = screen[(y + startY) * bufferWidth + startX + x - 1] & 255;
}
if ((x + startX) < 38) {
next = screen[(y + startY) * bufferWidth + startX + x + 2] & 255;
}
// First byte, compared with a sliding window encompassing the previous byte, if any.
int leastError = Integer.MAX_VALUE;
for (int hi = 0; hi < 2; hi++) {
int b1 = (hi << 7) | (bb1 & 0x07f);
int totalError = 0;
for (int c = 0; c < 7; c++) {
// for (int c = 6; c >= 0; c--) {
int on = b1 | (1 << c);
int off = on ^ (1 << c);
// get values for "off"
int i = hgrToDhgr[0][prev];
scanline[0] = i & 0x0fffffff;
i = hgrToDhgr[(i & 0x10000000) != 0 ? off | 0x0100 : off][bb2];
scanline[1] = i & 0x0fffffff;
// scanline[2] = hgrToDhgr[(i & 0x10000000) != 0 ? next | 0x0100 : next][0] & 0x0fffffff;
int errorOff = getError(x * 14 - overlap + c * 2, y, 28 + c * 2 - overlap + pixelShift, errorWindow, pixels, tmpScaled.getPixelReader(), scanline);
int off1 = pixels.get(c * 2 + 28 + pixelShift);
int off2 = pixels.get(c * 2 + 29 + pixelShift);
// get values for "on"
i = hgrToDhgr[0][prev];
scanline[0] = i & 0x0fffffff;
i = hgrToDhgr[(i & 0x10000000) != 0 ? on | 0x0100 : on][bb2];
scanline[1] = i & 0x0fffffff;
// scanline[2] = hgrToDhgr[(i & 0x10000000) != 0 ? next | 0x0100 : next][0] & 0x0fffffff;
int errorOn = getError(x * 14 - overlap + c * 2, y, 28 + c * 2 - overlap + pixelShift, errorWindow, pixels, tmpScaled.getPixelReader(), scanline);
int on1 = pixels.get(c * 2 + 28 + pixelShift);
int on2 = pixels.get(c * 2 + 29 + pixelShift);
int[] col1;
int[] col2;
if (errorOff < errorOn) {
totalError += errorOff;
b1 = off;
col1 = Palette.parseIntColor(off1);
col2 = Palette.parseIntColor(off2);
} else {
totalError += errorOn;
b1 = on;
col1 = Palette.parseIntColor(on1);
col2 = Palette.parseIntColor(on2);
}
if (pass >= nonErrorPasses) {
propagateError(x * 14 + c * 2, y, tmpScaled, col1, true, false);
propagateError(x * 14 + c * 2 + 1, y, tmpScaled, col2, false, true);
}
}
if (totalError < leastError) {
keepScaled.getPixelWriter().setPixels(0, y, 560, (y < 191) ? 2 : 1, tmpScaled.getPixelReader(), 0, y);
leastError = totalError;
bb1 = b1;
} else {
tmpScaled.getPixelWriter().setPixels(0, y, 560, (y < 191) ? 2 : 1, keepScaled.getPixelReader(), 0, y);
}
}
// Second byte, compared with a sliding window encompassing the next byte, if any.
leastError = Integer.MAX_VALUE;
for (int hi = 0; hi < 2; hi++) {
int b2 = (hi << 7) | (bb2 & 0x07f);
int totalError = 0;
for (int c = 0; c < 7; c++) {
// for (int c = 6; c >= 0; c--) {
int on = b2 | (1 << c);
int off = on ^ (1 << c);
// get values for "off"
int i = hgrToDhgr[bb1][off];
scanline[0] = i & 0xfffffff;
scanline[1] = hgrToDhgr[(i & 0x10000000) != 0 ? next | 0x0100 : next][0];
int errorOff = getError(x * 14 + 14 - overlap + c * 2, y, 14 - overlap + c * 2 + pixelShift, errorWindow, pixels, tmpScaled.getPixelReader(), scanline);
int off1 = pixels.get(c * 2 + 14 + pixelShift);
int off2 = pixels.get(c * 2 + 15 + pixelShift);
// get values for "on"
i = hgrToDhgr[bb1][on];
scanline[0] = i & 0xfffffff;
scanline[1] = hgrToDhgr[(i & 0x10000000) != 0 ? next | 0x0100 : next][0];
int errorOn = getError(x * 14 + 14 - overlap + c * 2, y, 14 - overlap + c * 2 + pixelShift, errorWindow, pixels, tmpScaled.getPixelReader(), scanline);
int on1 = pixels.get(c * 2 + 14 + pixelShift);
int on2 = pixels.get(c * 2 + 15 + pixelShift);
int[] col1;
int[] col2;
if (errorOff < errorOn) {
totalError += errorOff;
b2 = off;
col1 = Palette.parseIntColor(off1);
col2 = Palette.parseIntColor(off2);
} else {
totalError += errorOn;
b2 = on;
col1 = Palette.parseIntColor(on1);
col2 = Palette.parseIntColor(on2);
}
if (pass >= nonErrorPasses) {
propagateError(x * 14 + c * 2 + 14, y, tmpScaled, col1, true, false);
propagateError(x * 14 + c * 2 + 15, y, tmpScaled, col2, false, true);
}
}
if (totalError < leastError) {
keepScaled.getPixelWriter().setPixels(0, y, 560, (y < 191) ? 2 : 1, tmpScaled.getPixelReader(), 0, y);
leastError = totalError;
bb2 = b2;
} else {
tmpScaled.getPixelWriter().setPixels(0, y, 560, (y < 191) ? 2 : 1, keepScaled.getPixelReader(), 0, y);
}
}
screen[(y + startY) * bufferWidth + startX + x] = (byte) bb1;
screen[(y + startY) * bufferWidth + startX + x + 1] = (byte) bb2;
}
void doubleHiresDither(final byte[] screen, int y, int x, int[] scanline, List<Integer> pixels, WritableImage tmpScaled, int pass, final WritableImage keepScaled) {
if (x % 4 != 0) {
return;
}
scanline[0] = 0;
if (x >= 4) {
scanline[0] = screen[y * 80 + x - 1] << 21;
}
scanline[1] = 0;
if (x < 76) {
scanline[2] = screen[y * 80 + x + 4];
}
int bytes[] = new int[]{
screen[y * 80 + x] & 255,
screen[y * 80 + x + 1] & 255,
screen[y * 80 + x + 2] & 255,
screen[y * 80 + x + 3] & 255
};
for (int xx = 0; xx < 4; xx++) {
// First byte, compared with a sliding window encompassing the previous byte, if any.
int leastError = Integer.MAX_VALUE;
int b1 = (bytes[xx] & 0x07f);
for (int c = 0; c < 7; c++) {
int on = b1 | (1 << c);
int off = on ^ (1 << c);
// get values for "off"
int i = (xx == 3) ? off : bytes[3] & 255;
i <<= 7;
i |= (xx == 2) ? off : bytes[2] & 255;
i <<= 7;
i |= (xx == 1) ? off : bytes[1] & 255;
i <<= 7;
i |= (xx == 0) ? off : bytes[0] & 255;
scanline[1] = i;
int errorOff = getError((x + xx) * 7 - overlap + c, y, 28 + (xx * 7) + c - overlap + pixelShift, errorWindow, pixels, tmpScaled.getPixelReader(), scanline);
int off1 = pixels.get(xx * 7 + c + 28 + pixelShift);
// get values for "on"
i = (xx == 3) ? on : bytes[3] & 255;
i <<= 7;
i |= (xx == 2) ? on : bytes[2] & 255;
i <<= 7;
i |= (xx == 1) ? on : bytes[1] & 255;
i <<= 7;
i |= (xx == 0) ? on : bytes[0] & 255;
scanline[1] = i;
int errorOn = getError((x + xx) * 7 - overlap + c, y, 28 + (xx * 7) + c - overlap + pixelShift, errorWindow, pixels, tmpScaled.getPixelReader(), scanline);
int on1 = pixels.get(xx * 7 + c + 28 + pixelShift);
int[] col1;
if (errorOff < errorOn) {
// totalError += errorOff;
b1 = off;
col1 = Palette.parseIntColor(off1);
} else {
// totalError += errorOn;
b1 = on;
col1 = Palette.parseIntColor(on1);
}
if (pass >= nonErrorPasses) {
propagateError((x + xx) * 7 + c, y, tmpScaled, col1, false, false);
}
}
// if (totalError < leastError) {
keepScaled.getPixelWriter().setPixels(0, y, 560, (y < 191) ? 2 : 1, tmpScaled.getPixelReader(), 0, y);
// leastError = totalError;
bytes[xx] = b1;
// } else {
// tmpScaled.getPixelWriter().setPixels(0, y, 560, (y < 191) ? 2 : 1, keepScaled.getPixelReader(), 0, y);
}
screen[(y + startY) * bufferWidth + startX + x] = (byte) bytes[0];
screen[(y + startY) * bufferWidth + startX + x + 1] = (byte) bytes[1];
screen[(y + startY) * bufferWidth + startX + x + 2] = (byte) bytes[2];
screen[(y + startY) * bufferWidth + startX + x + 3] = (byte) bytes[3];
}
});
t.start();
// progress.close();
}
private static void propagateError(int x, int y, WritableImage img, int[] newColor, boolean propagateLeft, boolean propagateRight) {
int solid = 255 << 24;
for (int i = 0; i < 3; i++) {
if (x + 1 < img.getWidth() && propagateRight) {
int error = Palette.getComponent(img.getPixelReader().getArgb(x + 1, y), i) - newColor[i];
int c = img.getPixelReader().getArgb(x + 1, y);
img.getPixelWriter().setArgb(x + 1, y, solid | Palette.addError(c, i, (error * 7) >> 4));
}
if (y + 1 < img.getHeight()) {
int error = Palette.getComponent(img.getPixelReader().getArgb(x, y), i) - newColor[i];
if (x - 1 > 0 && propagateLeft) {
int c = img.getPixelReader().getArgb(x - 1, y + 1);
img.getPixelWriter().setArgb(x - 1, y + 1, solid | Palette.addError(c, i, (error * 3) >> 4));
}
int c = img.getPixelReader().getArgb(x, y + 1);
img.getPixelWriter().setArgb(x, y + 1, solid | Palette.addError(c, i, (error * 5) >> 4));
if (x + 1 < img.getWidth() && propagateRight) {
c = img.getPixelReader().getArgb(x + 1, y + 1);
img.getPixelWriter().setArgb(x + 1, y + 1, solid | Palette.addError(c, i, error >> 4));
}
}
}
}
private static int getError(int imageXStart, int y, int scanlineXStart, int window, final List<Integer> pixels, PixelReader source, int[] scanline) {
pixels.clear();
PixelWriter fakeWriter = new PixelWriter() {
@Override
public PixelFormat getPixelFormat() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setArgb(int x, int y, int c) {
pixels.add(c);
}
@Override
public void setColor(int i, int i1, Color color) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public <T extends Buffer> void setPixels(int i, int i1, int i2, int i3, PixelFormat<T> pf, T t, int i4) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setPixels(int i, int i1, int i2, int i3, PixelFormat<ByteBuffer> pf, byte[] bytes, int i4, int i5) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setPixels(int i, int i1, int i2, int i3, PixelFormat<IntBuffer> pf, int[] ints, int i4, int i5) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setPixels(int i, int i1, int i2, int i3, PixelReader reader, int i4, int i5) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
};
AppleImageRenderer.renderScanline(fakeWriter, 0, scanline, true, false, 20);
double max = 0;
double min = Double.MAX_VALUE;
double total = 0;
List<Double> err = new ArrayList<>();
for (int p = 0; p < window; p++) {
if ((imageXStart + p) < 0 || (imageXStart + p) >= 560) {
continue;
}
int[] c1 = Palette.parseIntColor(pixels.get(scanlineXStart + p));
int[] c2 = Palette.parseIntColor(source.getArgb(imageXStart + p, y));
double dist = Palette.distance(c1, c2);
total += dist;
max = Math.max(dist, max);
min = Math.min(dist, min);
err.add(dist);
}
// double avg = total/((double) window);
// double range = max-min;
// double totalDev = 0.0;
// for (Double d : err) {
// totalDev = Math.pow(d-avg, 2);
//// errorTotal += (d-min)/range;
// }
// totalDev /= ((double) window);
// double stdDev = Math.sqrt(totalDev);
// return (int) (min+(avg*(stdDev/range)));
return (int) total;
}
// int currentPixel = source.getRGB(x, y);
//
// for (int i = 0; i < 3; i++) {
// int error = Palette.getComponent(currentPixel, i) - Palette.getComponent(closestColor, i);
// if (x + 1 < source.getWidth()) {
// int c = source.getRGB(x + 1, y);
// source.setRGB(x + 1, y, Palette.addError(c, i, (error * 7) >> 4));
// }
// if (y + 1 < source.getHeight()) {
// if (x - 1 > 0) {
// int c = source.getRGB(x - 1, y + 1);
// source.setRGB(x - 1, y + 1, Palette.addError(c, i, (error * 3) >> 4));
// }
// {
// int c = source.getRGB(x, y + 1);
// source.setRGB(x, y + 1, Palette.addError(c, i, (error * 5) >> 4));
// }
// if (x + 1 < source.getWidth()) {
// int c = source.getRGB(x + 1, y + 1);
// source.setRGB(x + 1, y + 1, Palette.addError(c, i, error >> 4));
// }
// }
// }
// }
// }
// return dest;
// }
private static WritableImage getScaledImage(Image img, int width, int height) {
Canvas c = new Canvas(width, height);
c.getGraphicsContext2D().drawImage(img, 0, 0, width, height);
WritableImage newImg = new WritableImage(width, height);
SnapshotParameters sp = new SnapshotParameters();
c.snapshot(sp, newImg);
return newImg;
}
}

View File

@ -0,0 +1,415 @@
package org.badvision.outlaweditor.apple;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.image.Image;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import org.badvision.outlaweditor.Platform;
import static org.badvision.outlaweditor.apple.AppleNTSCGraphics.hgrToDhgr;
/* Copyright (c) 2013 the authors listed at the following URL, and/or
the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Floyd-Steinberg_dithering_(Java)?action=history&offset=20080201121723
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Retrieved from: http://en.literateprograms.org/Floyd-Steinberg_dithering_(Java)?oldid=12476
* Original code by Spoon! (Feb 2008)
* Modified and adapted to work with Apple Game Server by Brendan Robert (2013)
* Some of the original code of this class was migrated over to the Palette class which already manages colors in AGS.
*/
public class ImageDitherEngine {
int byteRenderWidth;
int pixelRenderWidth;
final int errorWindow = 6;
final int overlap = 3;
final int pixelShiftHgr = -1;
final int pixelShiftDhgr = -2;
WritableImage source;
byte[] screen;
Platform platform;
int bufferWidth;
int height;
int divisor;
public int[][] coefficients;
public ImageDitherEngine(Platform platform) {
this.platform = platform;
byteRenderWidth = platform == Platform.AppleII_DHGR ? 7 : 14;
}
public Platform getPlatform() {
return platform;
}
public void setSourceImage(Image img) {
source = getScaledImage(img, pixelRenderWidth, height);
}
private static WritableImage getScaledImage(Image img, int width, int height) {
Canvas c = new Canvas(width, height);
c.getGraphicsContext2D().drawImage(img, 0, 0, width, height);
WritableImage newImg = new WritableImage(width, height);
SnapshotParameters sp = new SnapshotParameters();
c.snapshot(sp, newImg);
return newImg;
}
public WritableImage getPreviewImage() {
return platform.imageRenderer.renderImage(null, screen, bufferWidth, height);
}
public void setOutputDimensions(int width, int height) {
this.bufferWidth = width;
this.pixelRenderWidth = width * byteRenderWidth;
this.height = height;
screen = platform.imageRenderer.createImageBuffer(width, height);
}
public void setDivisor(int divisor) {
this.divisor = divisor;
}
public void setCoefficients(int[][] coefficients) {
this.coefficients = coefficients;
}
int startX;
int startY;
public void setTargetCoordinates(int x, int y) {
startX = x;
startY = y;
}
int[][][] primaryScratchBuffer;
int[][][] secondaryScratchBuffer;
int[][][] tertriaryScratchBuffer;
int[] scanline;
List<Integer> pixels;
public byte[] dither(boolean propagateError) {
primaryScratchBuffer = generateScratchBuffer(source.getPixelReader(), pixelRenderWidth, height);
secondaryScratchBuffer = generateScratchBuffer(source.getPixelReader(), pixelRenderWidth, height);
tertriaryScratchBuffer = generateScratchBuffer(source.getPixelReader(), pixelRenderWidth, height);
for (int i = 0; i < screen.length; i++) {
screen[i] = (byte) 0;
}
scanline = new int[3];
pixels = new ArrayList<>();
for (int y = 0; y < height; y++) {
for (int x = 0; x < bufferWidth; x += 2) {
switch (platform) {
case AppleII:
hiresDither(y, x, propagateError);
break;
case AppleII_DHGR:
doubleHiresDither(y, x, propagateError);
break;
}
}
}
return screen;
}
void hiresDither(int y, int x, boolean propagateError) {
int bb1 = screen[(y + startY) * bufferWidth + startX + x] & 255;
int bb2 = screen[(y + startY) * bufferWidth + startX + x + 1] & 255;
int next = bb2 & 127; // Preserve hi-bit so last pixel stays solid, it is a very minor detail
int prev = 0;
if ((x + startX) > 0) {
prev = screen[(y + startY) * bufferWidth + startX + x - 1] & 255;
}
if ((x + startX) < (bufferWidth - 2)) {
next = screen[(y + startY) * bufferWidth + startX + x + 2] & 255;
}
// First byte, compared with a sliding window encompassing the previous byte, if any.
long leastError = Long.MAX_VALUE;
for (int hi = 0; hi < 2; hi++) {
copyBuffer(primaryScratchBuffer, tertriaryScratchBuffer, y, y+3);
int b1 = (hi << 7);
long totalError = 0;
for (int c = 0; c < 7; c++) {
int xx = x * 14 + c * 2;
int on = b1 | (1 << c);
int off = on ^ (1 << c);
// get values for "off"
int i = hgrToDhgr[0][prev];
scanline[0] = i;
i = hgrToDhgr[(i & 0x010000000) >> 20 | off][bb2];
scanline[1] = i;
double errorOff = getError(xx - overlap, y, 28 + c * 2 - overlap + pixelShiftHgr, errorWindow, tertriaryScratchBuffer, scanline);
int off1 = pixels.get(c * 2 + 28 + pixelShiftHgr);
int off2 = pixels.get(c * 2 + 29 + pixelShiftHgr);
// get values for "on"
i = hgrToDhgr[0][prev];
scanline[0] = i;
i = hgrToDhgr[(i & 0x010000000) >> 20 | on][bb2];
scanline[1] = i;
double errorOn = getError(xx - overlap, y, 28 + c * 2 - overlap + pixelShiftHgr, errorWindow, tertriaryScratchBuffer, scanline);
int on1 = pixels.get(c * 2 + 28 + pixelShiftHgr);
int on2 = pixels.get(c * 2 + 29 + pixelShiftHgr);
int[] col1;
int[] col2;
if (errorOff < errorOn) {
totalError += errorOff;
b1 = off;
col1 = Palette.parseIntColor(off1);
col2 = Palette.parseIntColor(off2);
} else {
totalError += errorOn;
b1 = on;
col1 = Palette.parseIntColor(on1);
col2 = Palette.parseIntColor(on2);
}
if (propagateError) {
propagateError(xx + pixelShiftHgr, y, tertriaryScratchBuffer, col1);
propagateError(xx + 1 + pixelShiftHgr, y, tertriaryScratchBuffer, col2);
}
}
if (totalError < leastError) {
copyBuffer(tertriaryScratchBuffer, secondaryScratchBuffer, y, y+3);
leastError = totalError;
bb1 = b1;
}
}
copyBuffer(secondaryScratchBuffer, primaryScratchBuffer, y, y+3);
// Second byte, compared with a sliding window encompassing the next byte, if any.
leastError = Long.MAX_VALUE;
for (int hi = 0; hi < 2; hi++) {
copyBuffer(primaryScratchBuffer, tertriaryScratchBuffer, y, y+3);
int b2 = (hi << 7);
long totalError = 0;
for (int c = 0; c < 7; c++) {
int xx = x * 14 + c * 2 + 14;
int on = b2 | (1 << c);
int off = on ^ (1 << c);
// get values for "off"
int i = hgrToDhgr[bb1][off];
scanline[0] = i;
scanline[1] = hgrToDhgr[(i & 0x010000000) >> 20 | next][0];
double errorOff = getError(xx - overlap, y, 14 + c * 2 - overlap + pixelShiftHgr, errorWindow, tertriaryScratchBuffer, scanline);
int off1 = pixels.get(c * 2 + 14 + pixelShiftHgr);
int off2 = pixels.get(c * 2 + 15 + pixelShiftHgr);
// get values for "on"
i = hgrToDhgr[bb1][on];
scanline[0] = i;
scanline[1] = hgrToDhgr[(i & 0x010000000) >> 20 | next][0];
double errorOn = getError(xx - overlap, y, 14 + c * 2 - overlap + pixelShiftHgr, errorWindow, tertriaryScratchBuffer, scanline);
int on1 = pixels.get(c * 2 + 14 + pixelShiftHgr);
int on2 = pixels.get(c * 2 + 15 + pixelShiftHgr);
int[] col1;
int[] col2;
if (errorOff < errorOn) {
totalError += errorOff;
b2 = off;
col1 = Palette.parseIntColor(off1);
col2 = Palette.parseIntColor(off2);
} else {
totalError += errorOn;
b2 = on;
col1 = Palette.parseIntColor(on1);
col2 = Palette.parseIntColor(on2);
}
if (propagateError) {
propagateError(xx + pixelShiftHgr, y, tertriaryScratchBuffer, col1);
propagateError(xx + 1 + pixelShiftHgr, y, tertriaryScratchBuffer, col2);
}
}
if (totalError < leastError) {
copyBuffer(tertriaryScratchBuffer, secondaryScratchBuffer, y, y+3);
leastError = totalError;
bb2 = b2;
}
}
copyBuffer(secondaryScratchBuffer, primaryScratchBuffer, y, y+3);
screen[(y + startY) * bufferWidth + startX + x] = (byte) bb1;
screen[(y + startY) * bufferWidth + startX + x + 1] = (byte) bb2;
}
void doubleHiresDither(int y, int x, boolean propagateError) {
if (x % 4 != 0) {
return;
}
scanline[0] = 0;
if (x >= 4) {
scanline[0] = screen[y * bufferWidth + x - 1] << 21;
}
scanline[1] = 0;
scanline[2] = 0;
if (x + 4 < bufferWidth) {
scanline[2] = screen[y * bufferWidth + x + 4];
}
int bytes[] = new int[]{
screen[y * bufferWidth + x] & 255,
screen[y * bufferWidth + x + 1] & 255,
screen[y * bufferWidth + x + 2] & 255,
screen[y * bufferWidth + x + 3] & 255
};
for (int byteOffset = 0; byteOffset < 4; byteOffset++) {
// First byte, compared with a sliding window encompassing the previous byte, if any.
int b1 = (bytes[byteOffset] & 0x07f);
for (int bit = 0; bit < 7; bit++) {
int on = b1 | (1 << bit);
int off = on ^ (1 << bit);
// get values for "off"
int i = (byteOffset == 3) ? off : bytes[3] & 255;
i <<= 7;
i |= (byteOffset == 2) ? off : bytes[2] & 255;
i <<= 7;
i |= (byteOffset == 1) ? off : bytes[1] & 255;
i <<= 7;
i |= (byteOffset == 0) ? off : bytes[0] & 255;
scanline[1] = i;
double errorOff = getError((x + byteOffset) * 7 - overlap + bit, y, 28 + (byteOffset * 7) + bit - overlap + pixelShiftDhgr, errorWindow, primaryScratchBuffer, scanline);
int offColor = pixels.get(byteOffset * 7 + bit + 28 + pixelShiftDhgr);
// get values for "on"
i = (byteOffset == 3) ? on : bytes[3] & 255;
i <<= 7;
i |= (byteOffset == 2) ? on : bytes[2] & 255;
i <<= 7;
i |= (byteOffset == 1) ? on : bytes[1] & 255;
i <<= 7;
i |= (byteOffset == 0) ? on : bytes[0] & 255;
scanline[1] = i;
double errorOn = getError((x + byteOffset) * 7 - overlap + bit, y, 28 + (byteOffset * 7) + bit - overlap + pixelShiftDhgr, errorWindow, primaryScratchBuffer, scanline);
int onColor = pixels.get(byteOffset * 7 + bit + 28 + pixelShiftDhgr);
int[] col1;
if (errorOff < errorOn) {
b1 = off;
col1 = Palette.parseIntColor(offColor);
} else {
b1 = on;
col1 = Palette.parseIntColor(onColor);
}
if (propagateError) {
propagateError((x + byteOffset) * 7 + bit, y, primaryScratchBuffer, col1);
}
}
bytes[byteOffset] = b1;
screen[(y + startY) * bufferWidth + startX + x] = (byte) bytes[0];
screen[(y + startY) * bufferWidth + startX + x + 1] = (byte) bytes[1];
screen[(y + startY) * bufferWidth + startX + x + 2] = (byte) bytes[2];
screen[(y + startY) * bufferWidth + startX + x + 3] = (byte) bytes[3];
}
}
public static int ALPHA_SOLID = 255 << 24;
private void propagateError(int x, int y, int[][][] scratchBuffer, int[] newColor) {
if (x < 0 || y < 0) {
return;
}
int[] pixel = scratchBuffer[y][x];
for (int i = 0; i < 3; i++) {
double error = pixel[i] - newColor[i];
for (int yy = 0; yy < 3 && y + yy < scratchBuffer.length; yy++) {
for (int xx = -2; xx < 3 && x + xx < scratchBuffer[y].length; xx++) {
if (x + xx < 0 || coefficients[xx + 2][yy] == 0) {
continue;
}
int errorAmount = (int) ((error * coefficients[xx + 2][yy]) / divisor);
scratchBuffer[y+yy][x+xx][i] += errorAmount;
}
}
}
}
PixelWriter fakeWriter = new PixelWriter() {
@Override
public PixelFormat getPixelFormat() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void setArgb(int x, int y, int c) {
pixels.add(c);
}
@Override
public void setColor(int i, int i1, Color color) {
}
@Override
public <T extends Buffer> void setPixels(int i, int i1, int i2, int i3, PixelFormat<T> pf, T t, int i4) {
}
@Override
public void setPixels(int i, int i1, int i2, int i3, PixelFormat<ByteBuffer> pf, byte[] bytes, int i4, int i5) {
}
@Override
public void setPixels(int i, int i1, int i2, int i3, PixelFormat<IntBuffer> pf, int[] ints, int i4, int i5) {
}
@Override
public void setPixels(int i, int i1, int i2, int i3, PixelReader reader, int i4, int i5) {
}
};
private double getError(int imageXStart, int y, int scanlineXStart, int window, int[][][] source, int[] scanline) {
pixels.clear();
AppleImageRenderer.renderScanline(fakeWriter, 0, scanline, true, false, 20);
double total = 0;
for (int p = 0; p < window; p++) {
if ((imageXStart + p) < 0 || (imageXStart + p) >= pixelRenderWidth || scanlineXStart + p < 0) {
continue;
}
int[] c1 = Palette.parseIntColor(pixels.get(scanlineXStart + p));
int[] c2 = source[y][imageXStart + p];
double dist = Palette.distance(c1, c2);
total += dist;
}
return (int) total;
}
private int[][][] generateScratchBuffer(PixelReader pixelReader, int pixelRenderWidth, int height) {
int[][][] out = new int[height][pixelRenderWidth][3];
for (int y = 0; y < height; y++) {
for (int x=0; x < pixelRenderWidth; x++) {
int pixel = pixelReader.getArgb(x, y);
out[y][x] = Palette.parseIntColor(pixel);
}
}
return out;
}
private void copyBuffer(int[][][] source, int[][][] target, int start, int end) {
for (int y=start; y < end && y < source.length; y++) {
int width = source[y].length;
for (int x=0; x < width; x++) {
System.arraycopy(source[y][x], 0, target[y][x], 0, 3);
}
}
}
}

View File

@ -52,11 +52,11 @@ public abstract class Palette {
}
public int findColor(int color[]) {
int lastDiff = COLOR_DISTANCE_MAX;
double lastDiff = COLOR_DISTANCE_MAX;
int bestFit = 0;
for (int i = 0; i < colors.size(); i++) {
int test[] = (int[]) colors.get(i);
int diff = (int) distance(color, test);
double diff = distance(color, test);
if (diff < lastDiff) {
lastDiff = diff;
bestFit = i;
@ -66,8 +66,19 @@ public abstract class Palette {
return bestFit;
}
public static double distance(int color[], int test[]) {
return Math.pow(Math.abs(color[0] - test[0]), 3D) + Math.pow(Math.abs(color[1] - test[1]), 3D) + Math.pow(Math.abs(color[2] - test[2]), 3D);
public static double distance(int c1[], int c2[]) {
double rmean = ( c1[0] + c2[1] ) / 2.0;
double r = c1[0] - c2[0];
double g = c1[1] - c2[1];
double b = c1[2] - c2[2];
double weightR = 2.0 + rmean/256.0;
double weightG = 4.0;
double weightB = 2.0 + (255.0-rmean)/256.0;
return Math.sqrt(weightR*(r*r) + weightG*(g*g) + weightB*(b*b)) / 1.73167;
}
public static double distance_linear(int color[], int test[]) {
return Math.sqrt(Math.pow(color[0] - test[0], 2D) + Math.pow(color[1] - test[1], 2D) + Math.pow(color[2] - test[2], 2D));
}
public static int getR(int color) {
@ -94,10 +105,4 @@ public abstract class Palette {
return 0;
}
}
public static int addError(int color, int component, int error) {
int[] sourceColor = parseIntColor(color);
sourceColor[component] = Math.max(0, Math.min(255, sourceColor[component] + error));
return toRGBInt(sourceColor);
}
}

View File

@ -50,16 +50,16 @@ public class AppleDHGRImageRenderer extends AppleImageRenderer {
return buffer;
}
// @Override
// public WritableImage renderImage(WritableImage img, byte[] rawImage) {
// if (img == null) {
// img = new WritableImage(560, 384);
// }
// for (int y = 0; y < 192; y++) {
// renderScanline(img, y, rawImage);
// }
// return img;
// }
@Override
public WritableImage renderImage(WritableImage img, byte[] rawImage, int width, int height) {
if (img == null) {
img = new WritableImage(width * 7, height * 2);
}
for (int y = 0; y < height; y++) {
renderScanline(img, y, width, rawImage);
}
return img;
}
@Override
public WritableImage renderScanline(WritableImage img, int y, int width, byte[] rawImage) {

View File

@ -1,18 +1,16 @@
package org.badvision.outlaweditor.apple.dhgr;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.control.Menu;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import org.badvision.outlaweditor.Platform;
import org.badvision.outlaweditor.TileEditor;
import org.badvision.outlaweditor.data.DataObserver;
import org.badvision.outlaweditor.data.xml.Tile;
import org.badvision.outlaweditor.data.TileUtils;
@ -34,7 +32,7 @@ public class AppleDHGRTileEditor extends TileEditor {
}
@Override
public void buildEditorUI(AnchorPane tileEditorAnchorPane) {
public void buildEditorUI(Pane tileEditorAnchorPane) {
grid = new Rectangle[28][16];
gridGroup = new Group();
for (int y = 0; y < 16; y++) {
@ -42,19 +40,13 @@ public class AppleDHGRTileEditor extends TileEditor {
final int xx = x;
final int yy = y;
Rectangle rect = new Rectangle((zoom/2) * x + 5, zoom * y + 5, zoom/2 - 2, zoom - 2);
rect.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
performDragAction((int) (t.getX() / (zoom/2)), (int) (t.getY() / zoom));
}
rect.setOnMouseDragged((MouseEvent t) -> {
performDragAction((int) (t.getX() / (zoom/2)), (int) (t.getY() / zoom));
});
rect.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
handleMouse(t, xx, yy);
lastActionX=-1;
lastActionY=-1;
}
rect.setOnMousePressed((MouseEvent t) -> {
handleMouse(t, xx, yy);
lastActionX=-1;
lastActionY=-1;
});
grid[x][y] = rect;
gridGroup.getChildren().add(rect);
@ -145,11 +137,8 @@ public class AppleDHGRTileEditor extends TileEditor {
@Override
public void buildPatternSelector(Menu tilePatternMenu) {
FillPattern.buildMenu(tilePatternMenu, new DataObserver<FillPattern>() {
@Override
public void observedObjectChanged(FillPattern object) {
changeCurrentPattern(object);
}
FillPattern.buildMenu(tilePatternMenu, (FillPattern object) -> {
changeCurrentPattern(object);
});
}

View File

@ -0,0 +1,10 @@
package org.badvision.outlaweditor.ui;
/**
*
* @author blurry
*/
@FunctionalInterface
public interface ImageConversionPostAction {
public void storeConvertedImage(byte[] image);
}

View File

@ -2,9 +2,10 @@ package org.badvision.outlaweditor.ui;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.Group;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Menu;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import org.badvision.outlaweditor.Editor;
@ -20,6 +21,12 @@ public abstract class ImageEditorTabController {
protected TextField imageCategoryField; // Value injected by FXMLLoader
@FXML // fx:id="imageEditorAnchorPane"
protected AnchorPane imageEditorAnchorPane; // Value injected by FXMLLoader
@FXML
protected ScrollPane imageEditorScrollPane;
@FXML
protected Group imageEditorZoomGroup;
@FXML
protected AnchorPane imageEditorScrollAnchorPane;
@FXML // fx:id="imageHeightField"
protected TextField imageHeightField; // Value injected by FXMLLoader
@FXML // fx:id="imageNameField"
@ -40,6 +47,9 @@ public abstract class ImageEditorTabController {
assert imagePatternMenu != null : "fx:id=\"imagePatternMenu\" was not injected: check your FXML file 'ApplicationUI.fxml'.";
assert imageSelector != null : "fx:id=\"imageSelector\" was not injected: check your FXML file 'ApplicationUI.fxml'.";
assert imageWidthField != null : "fx:id=\"imageWidthField\" was not injected: check your FXML file 'ApplicationUI.fxml'.";
assert imageEditorScrollPane != null : "fx:id\"imageEditorScrollPane\" was not injected: check your FXML file 'ApplicationUI.fxml'";
assert imageEditorZoomGroup != null : "fx:id\"imageEditorZoomGroup\" was not injected: check your FXML file 'ApplicationUI.fxml'";
assert imageEditorScrollAnchorPane != null : "fx:id\"imageEditorScrollAnchorPane\" was not injected: check your FXML file 'ApplicationUI.fxml'";
}
abstract public void rebuildImageSelector();
@ -95,21 +105,6 @@ public abstract class ImageEditorTabController {
@FXML
abstract public void onImageSelected(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageDown(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageLeft(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageRight(ActionEvent event);
// Handler for Button[Button[id=null, styleClass=button moveButton]] onAction
@FXML
abstract public void scrollImageUp(ActionEvent event);
@FXML
abstract public void imageDraw5BitMode(ActionEvent event);

View File

@ -12,7 +12,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
@ -22,6 +22,7 @@ import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBoxBuilder;
import javafx.scene.layout.VBoxBuilder;
import javafx.scene.text.Text;
@ -31,9 +32,11 @@ import javax.xml.bind.JAXB;
import org.badvision.outlaweditor.Application;
import org.badvision.outlaweditor.FileUtils;
import org.badvision.outlaweditor.MythosEditor;
import org.badvision.outlaweditor.apple.ImageDitherEngine;
import org.badvision.outlaweditor.data.TilesetUtils;
import org.badvision.outlaweditor.data.xml.GameData;
import org.badvision.outlaweditor.data.xml.Script;
import org.badvision.outlaweditor.ui.impl.ImageConversionWizardController;
/**
*
@ -120,14 +123,11 @@ public class UIAction {
currentMenu = new Menu(action.name().replace("_", ""));
} else {
MenuItem item = new MenuItem(action.name().replaceAll("_", " "));
item.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
try {
actionPerformed(action);
} catch (IOException ex) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
}
item.setOnAction((ActionEvent t) -> {
try {
actionPerformed(action);
} catch (IOException ex) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
}
});
currentMenu.getItems().add(item);
@ -139,12 +139,11 @@ public class UIAction {
}
public static void quit() {
confirm("Quit? Are you sure?", new Runnable() {
@Override
public void run() {
Platform.exit();
}
}, null);
confirm("Quit? Are you sure?", UIAction::quitWithoutConfirming, null);
}
public static void quitWithoutConfirming() {
Platform.runLater(Platform::exit);
}
static Image badImage;
@ -181,14 +180,11 @@ public class UIAction {
List<Button> buttons = new ArrayList<>();
for (final Choice c : choices) {
Button b = new Button(c.text);
b.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
if (c.handler != null) {
c.handler.run();
}
dialogStage.close();
b.setOnAction((ActionEvent t) -> {
if (c.handler != null) {
c.handler.run();
}
dialogStage.close();
});
buttons.add(b);
}
@ -216,4 +212,24 @@ public class UIAction {
editor.show();
return script;
}
public static ImageConversionWizardController openImageConversionModal(Image image, ImageDitherEngine ditherEngine, int targetWidth, int targetHeight, ImageConversionPostAction postAction) {
FXMLLoader fxmlLoader = new FXMLLoader(UIAction.class.getResource("/imageConversionWizard.fxml"));
try {
Stage primaryStage = new Stage();
AnchorPane node = (AnchorPane) fxmlLoader.load();
ImageConversionWizardController controller = fxmlLoader.getController();
controller.setDitherEngine(ditherEngine);
controller.setOutputDimensions(targetWidth, targetHeight);
controller.setPostAction(postAction);
controller.setSourceImage(image);
Scene s = new Scene(node);
primaryStage.setScene(s);
primaryStage.show();
controller.setStage(primaryStage);
return controller;
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}

View File

@ -0,0 +1,400 @@
package org.badvision.outlaweditor.ui.impl;
import java.net.URL;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;
import javafx.stage.Stage;
import org.badvision.outlaweditor.apple.ImageDitherEngine;
import org.badvision.outlaweditor.ui.ImageConversionPostAction;
/**
* FXML Controller class
*
* @author blurry
*/
public class ImageConversionWizardController implements Initializable {
@FXML
private TextField brightnessValue;
@FXML
private Slider brightnessSlider;
@FXML
private TextField contrastValue;
@FXML
private Slider contrastSlider;
@FXML
private TextField hueValue;
@FXML
private Slider hueSlider;
@FXML
private TextField saturationValue;
@FXML
private Slider saturationSlider;
@FXML
private TextField outputWidthValue;
@FXML
private TextField outputHeightValue;
@FXML
private TextField cropTopValue;
@FXML
private TextField cropLeftValue;
@FXML
private TextField cropBottomValue;
@FXML
private TextField cropRightValue;
@FXML
private TextField coefficientValue30;
@FXML
private TextField coefficientValue40;
@FXML
private TextField coefficientValue01;
@FXML
private TextField coefficientValue11;
@FXML
private TextField coefficientValue21;
@FXML
private TextField coefficientValue31;
@FXML
private TextField coefficientValue41;
@FXML
private TextField coefficientValue02;
@FXML
private TextField coefficientValue12;
@FXML
private TextField coefficientValue22;
@FXML
private TextField coefficientValue32;
@FXML
private TextField coefficientValue42;
private final int[][] diffusionCoeffficients = new int[5][3];
@FXML
private TextField divisorValue;
@FXML
private ImageView sourceImageView;
@FXML
private ImageView convertedImageView;
private ColorAdjust imageAdjustments = new ColorAdjust();
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
for (TextField field : new TextField[]{
brightnessValue, contrastValue, hueValue, saturationValue,
cropBottomValue, cropLeftValue, cropRightValue, cropTopValue,
coefficientValue01, coefficientValue02, coefficientValue11, coefficientValue12,
coefficientValue21, coefficientValue22, coefficientValue30, coefficientValue31,
coefficientValue32, coefficientValue40, coefficientValue41, coefficientValue41,
coefficientValue42, divisorValue, outputHeightValue, outputWidthValue
}) {
configureNumberValidation(field, "0");
}
brightnessValue.textProperty().bindBidirectional(brightnessSlider.valueProperty(), NumberFormat.getNumberInstance());
contrastValue.textProperty().bindBidirectional(contrastSlider.valueProperty(), NumberFormat.getNumberInstance());
hueValue.textProperty().bindBidirectional(hueSlider.valueProperty(), NumberFormat.getNumberInstance());
saturationValue.textProperty().bindBidirectional(saturationSlider.valueProperty(), NumberFormat.getNumberInstance());
brightnessValue.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue)
-> javafx.application.Platform.runLater(this::updateImageAdjustments));
contrastValue.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue)
-> javafx.application.Platform.runLater(this::updateImageAdjustments));
hueValue.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue)
-> javafx.application.Platform.runLater(this::updateImageAdjustments));
saturationValue.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue)
-> javafx.application.Platform.runLater(this::updateImageAdjustments));
configureAtkinsonPreset(null);
}
private Stage stage;
private ImageConversionPostAction postAction;
private Image sourceImage;
private WritableImage preprocessedImage;
private WritableImage outputPreviewImage;
private ImageDitherEngine ditherEngine;
public void setStage(Stage stage) {
this.stage = stage;
}
public void setPostAction(ImageConversionPostAction postAction) {
this.postAction = postAction;
}
public void setDitherEngine(ImageDitherEngine engine) {
this.ditherEngine = engine;
}
public void setSourceImage(Image image) {
sourceImage = image;
preprocessImage();
}
private void updateImageAdjustments() {
double hue = Double.parseDouble(hueValue.getText());
double saturation = Double.parseDouble(saturationValue.getText());
double brightness = Double.parseDouble(brightnessValue.getText());
double contrast = Double.parseDouble(contrastValue.getText());
imageAdjustments = new ColorAdjust();
imageAdjustments.setContrast(contrast);
imageAdjustments.setBrightness(brightness);
imageAdjustments.setHue(hue);
imageAdjustments.setSaturation(saturation);
sourceImageView.setEffect(imageAdjustments);
}
private void preprocessImage() {
PixelReader pixelReader = sourceImage.getPixelReader();
preprocessedImage = new WritableImage(pixelReader, (int) sourceImage.getWidth(), (int) sourceImage.getHeight());
updateSourceView(preprocessedImage);
}
public void setOutputDimensions(int targetWidth, int targetHeight) {
ditherEngine.setOutputDimensions(targetWidth, targetHeight);
outputWidthValue.setText(String.valueOf(targetWidth));
outputHeightValue.setText(String.valueOf(targetHeight));
outputPreviewImage = ditherEngine.getPreviewImage();
}
public int getOutputWidth() {
return Integer.parseInt(outputWidthValue.getText());
}
public int getOutputHeight() {
return Integer.parseInt(outputHeightValue.getText());
}
private void updateSourceView(Image image) {
sourceImageView.setImage(image);
sourceImageView.setFitWidth(0);
sourceImageView.setFitHeight(0);
int width = (int) image.getWidth();
int height = (int) image.getHeight();
defaultTextFieldValues.put(cropRightValue, String.valueOf(width));
defaultTextFieldValues.put(cropBottomValue, String.valueOf(height));
cropRightValue.setText(String.valueOf(width));
cropBottomValue.setText(String.valueOf(height));
}
@FXML
private void performQuantizePass(ActionEvent event) {
prepareForConversion();
byte[] out = ditherEngine.dither(false);
updateConvertedImageWithData(out);
}
@FXML
private void performDiffusionPass(ActionEvent event) {
prepareForConversion();
byte[] out = ditherEngine.dither(true);
updateConvertedImageWithData(out);
}
private void prepareForConversion() {
ditherEngine.setCoefficients(getCoefficients());
ditherEngine.setDivisor(getDivisor());
ditherEngine.setSourceImage(sourceImageView.snapshot(null, null));
}
byte[] lastOutput;
private void updateConvertedImageWithData(byte[] data) {
lastOutput = data;
convertedImageView.setImage(ditherEngine.getPreviewImage());
// convertedImageView.setImage(ditherEngine.getScratchBuffer());
}
@FXML
private void performOK(ActionEvent event) {
postAction.storeConvertedImage(lastOutput);
stage.close();
}
@FXML
private void performCancel(ActionEvent event) {
stage.close();
}
private final Map<TextField, String> defaultTextFieldValues = new HashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
private void configureNumberValidation(TextField field, String defaultValue) {
defaultTextFieldValues.put(field, defaultValue);
field.textProperty().addListener((ChangeListener) (ObservableValue observable, Object oldValue, Object newValue) -> {
if (newValue == null || "".equals(newValue)) {
scheduler.schedule(() -> {
if (null == field.textProperty().getValue() || field.textProperty().getValue().isEmpty()) {
field.textProperty().setValue(defaultTextFieldValues.get(field));
}
}, 250, TimeUnit.MILLISECONDS);
} else {
try {
Double.parseDouble(newValue.toString());
} catch (Exception ex) {
field.textProperty().setValue(oldValue.toString());
}
}
});
}
private void setCoefficients(int... coeff) {
coefficientValue30.setText(String.valueOf(coeff[3]));
coefficientValue40.setText(String.valueOf(coeff[4]));
coefficientValue01.setText(String.valueOf(coeff[5]));
coefficientValue11.setText(String.valueOf(coeff[6]));
coefficientValue21.setText(String.valueOf(coeff[7]));
coefficientValue31.setText(String.valueOf(coeff[8]));
coefficientValue41.setText(String.valueOf(coeff[9]));
coefficientValue02.setText(String.valueOf(coeff[10]));
coefficientValue12.setText(String.valueOf(coeff[11]));
coefficientValue22.setText(String.valueOf(coeff[12]));
coefficientValue32.setText(String.valueOf(coeff[13]));
coefficientValue42.setText(String.valueOf(coeff[14]));
}
private int[][] getCoefficients() {
diffusionCoeffficients[0][0] = 0;
diffusionCoeffficients[1][0] = 0;
diffusionCoeffficients[2][0] = 0;
diffusionCoeffficients[3][0] = Integer.parseInt(coefficientValue30.getText());
diffusionCoeffficients[4][0] = Integer.parseInt(coefficientValue40.getText());
diffusionCoeffficients[0][1] = Integer.parseInt(coefficientValue01.getText());
diffusionCoeffficients[1][1] = Integer.parseInt(coefficientValue11.getText());
diffusionCoeffficients[2][1] = Integer.parseInt(coefficientValue21.getText());
diffusionCoeffficients[3][1] = Integer.parseInt(coefficientValue31.getText());
diffusionCoeffficients[4][1] = Integer.parseInt(coefficientValue41.getText());
diffusionCoeffficients[0][2] = Integer.parseInt(coefficientValue02.getText());
diffusionCoeffficients[1][2] = Integer.parseInt(coefficientValue12.getText());
diffusionCoeffficients[2][2] = Integer.parseInt(coefficientValue22.getText());
diffusionCoeffficients[3][2] = Integer.parseInt(coefficientValue32.getText());
diffusionCoeffficients[4][2] = Integer.parseInt(coefficientValue42.getText());
return diffusionCoeffficients;
}
private void setDivisor(int div) {
divisorValue.setText(String.valueOf(div));
}
private int getDivisor() {
return Integer.valueOf(divisorValue.getText());
}
// http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/
@FXML
private void configureFloydSteinbergPreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 7, 0,
0, 3, 5, 1, 0,
0, 0, 0, 0, 0
);
// setDivisor(16);
setDivisor(18);
}
@FXML
private void configureFastFloydSteinbergPreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 3, 0,
0, 0, 3, 2, 0,
0, 0, 0, 0, 0
);
// setDivisor(8);
setDivisor(10);
}
@FXML
private void configureJarvisJudiceNinkePreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 7, 5,
3, 5, 7, 5, 3,
1, 3, 5, 3, 1
);
// setDivisor(48);
setDivisor(57);
}
@FXML
private void configureStuckiPreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 8, 4,
2, 4, 8, 4, 2,
1, 2, 4, 2, 1
);
// setDivisor(42);
setDivisor(52);
}
@FXML
private void configureAtkinsonPreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 1, 1,
0, 1, 1, 1, 0,
0, 0, 1, 0, 0
);
setDivisor(8);
}
@FXML
private void configureBurkesPreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 8, 4,
2, 4, 8, 4, 2,
0, 0, 0, 0, 0
);
setDivisor(37);
// setDivisor(32);
}
@FXML
private void configureSierraPreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 5, 3,
2, 4, 5, 4, 2,
0, 2, 3, 2, 0
);
// setDivisor(32);
setDivisor(41);
}
@FXML
private void configureTwoRowSierraPreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 4, 3,
1, 2, 3, 2, 1,
0, 0, 0, 0, 0
);
// setDivisor(16);
setDivisor(18);
}
@FXML
private void configureSierraLitePreset(ActionEvent event) {
setCoefficients(
0, 0, 0, 2, 0,
0, 1, 1, 0, 0,
0, 0, 0, 0, 0
);
// setDivisor(4);
setDivisor(5);
}
}

View File

@ -4,10 +4,8 @@ import org.badvision.outlaweditor.ui.EntitySelectorCell;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.ComboBoxListCell;
import javafx.util.Callback;
import org.badvision.outlaweditor.Application;
import org.badvision.outlaweditor.Editor;
import org.badvision.outlaweditor.ImageEditor;
@ -50,14 +48,9 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
}
}
});
imageSelector.setCellFactory(new Callback<ListView<Image>, ListCell<Image>>() {
imageSelector.setCellFactory((ListView<Image> param) -> new EntitySelectorCell<Image>(imageNameField) {
@Override
public ListCell<Image> call(ListView<Image> param) {
return new EntitySelectorCell<Image>(imageNameField) {
@Override
public void finishUpdate(Image item) {
}
};
public void finishUpdate(Image item) {
}
});
}
@ -120,6 +113,7 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
public void imageZoomIn(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.zoomIn();
updateScrollAreaWithScale(currentImageEditor.getZoomScale());
}
}
@ -127,6 +121,7 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
public void imageZoomOut(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.zoomOut();
updateScrollAreaWithScale(currentImageEditor.getZoomScale());
}
}
@ -149,14 +144,11 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
if (currentImage == null) {
return;
}
confirm("Delete image '" + currentImage.getName() + "'. Are you sure?", new Runnable() {
@Override
public void run() {
Image del = currentImage;
setCurrentImage(null);
Application.gameData.getImage().remove(del);
rebuildImageSelector();
}
confirm("Delete image '" + currentImage.getName() + "'. Are you sure?", () -> {
Image del = currentImage;
setCurrentImage(null);
Application.gameData.getImage().remove(del);
rebuildImageSelector();
}, null);
}
@ -172,34 +164,6 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
setCurrentImage(imageSelector.getSelectionModel().getSelectedItem());
}
@Override
public void scrollImageDown(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(0, 1);
}
}
@Override
public void scrollImageLeft(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(-1, 0);
}
}
@Override
public void scrollImageRight(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(1, 0);
}
}
@Override
public void scrollImageUp(ActionEvent event) {
if (currentImageEditor != null) {
currentImageEditor.scrollBy(0, -1);
}
}
private void setCurrentImage(Image i) {
if (currentImage != null && currentImage.equals(i)) {
return;
@ -239,8 +203,10 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
Logger.getLogger(ApplicationUIControllerImpl.class.getName()).log(Level.SEVERE, null, ex);
}
currentImageEditor.setEntity(i);
currentImageEditor.buildEditorUI(imageEditorAnchorPane);
currentImageEditor.buildEditorUI(imageEditorScrollAnchorPane);
currentImageEditor.buildPatternSelector(imagePatternMenu);
imageEditorZoomGroup.setScaleX(1.0);
imageEditorZoomGroup.setScaleY(1.0);
}
}
@ -255,4 +221,13 @@ public class ImageEditorTabControllerImpl extends ImageEditorTabController {
imageSelector.getItems().addAll(Application.gameData.getImage());
imageSelector.getSelectionModel().select(i);
}
private void updateScrollAreaWithScale(double zoomScale) {
double hval = imageEditorScrollPane.getHvalue();
double vval = imageEditorScrollPane.getVvalue();
imageEditorZoomGroup.setScaleX(zoomScale);
imageEditorZoomGroup.setScaleY(zoomScale);
imageEditorScrollPane.setHvalue(hval);
imageEditorScrollPane.setVvalue(vval);
}
}

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.scene.shape.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" maxHeight="482.0" maxWidth="600.0" prefHeight="482.0" prefWidth="600.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.badvision.outlaweditor.ui.impl.ImageConversionWizardController">
<stylesheets>
<URL value="@/styles/imageconversionwizard.css" />
</stylesheets>
<children>
<HBox layoutX="14.0" layoutY="14.0" styleClass="imageViews" AnchorPane.bottomAnchor="276.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<StackPane HBox.hgrow="ALWAYS">
<children>
<ScrollPane fitToWidth="true" minHeight="192.0" pannable="true" styleClass="imageViewScroll">
<content>
<AnchorPane minHeight="188.0" styleClass="imageView">
<children>
<ImageView fx:id="sourceImageView" fitHeight="185.0" fitWidth="271.0" pickOnBounds="true" preserveRatio="true" />
</children>
</AnchorPane>
</content>
</ScrollPane>
<Label alignment="BOTTOM_CENTER" text="Source Image" textAlignment="CENTER" StackPane.alignment="BOTTOM_CENTER">
<StackPane.margin>
<Insets bottom="-20.0" />
</StackPane.margin>
</Label>
</children>
</StackPane>
<Region prefHeight="1" prefWidth="14.0" />
<StackPane HBox.hgrow="ALWAYS">
<children>
<ScrollPane fitToWidth="true" minHeight="192.0" pannable="true" styleClass="imageViewScroll">
<content>
<AnchorPane minHeight="188.0" styleClass="imageView">
<children>
<ImageView fx:id="convertedImageView" fitHeight="185.0" fitWidth="271.0" pickOnBounds="true" preserveRatio="true" />
</children>
</AnchorPane>
</content>
</ScrollPane>
<Label alignment="BOTTOM_CENTER" text="Converted" textAlignment="CENTER" StackPane.alignment="BOTTOM_CENTER">
<StackPane.margin>
<Insets bottom="-20.0" />
</StackPane.margin>
</Label>
</children>
</StackPane>
</children>
</HBox>
<Separator layoutX="14.0" layoutY="227.0" prefHeight="9.0" prefWidth="442.0" AnchorPane.bottomAnchor="246.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" />
<TabPane layoutX="14.0" layoutY="231.0" prefHeight="203.0" prefWidth="582.0" side="BOTTOM" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="48.0" AnchorPane.leftAnchor="9.0" AnchorPane.rightAnchor="9.0">
<tabs>
<Tab text="Source Adjustments">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Label layoutX="14.0" layoutY="14.0" text="Brightness" AnchorPane.leftAnchor="9.0" />
<TextField fx:id="brightnessValue" layoutX="98.0" layoutY="9.0" prefHeight="26.0" prefWidth="60.0" />
<Slider fx:id="brightnessSlider" blockIncrement="0.1" layoutX="148.0" layoutY="15.0" majorTickUnit="0.5" max="1.0" min="-1.0" minorTickCount="10" prefHeight="16.0" prefWidth="415.0" showTickMarks="true" snapToTicks="true" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="0.0" />
<Label layoutX="14.0" layoutY="43.0" text="Contrast" AnchorPane.leftAnchor="9.0" />
<TextField fx:id="contrastValue" layoutX="98.0" layoutY="38.0" prefHeight="26.0" prefWidth="60.0" />
<Slider fx:id="contrastSlider" blockIncrement="0.1" layoutX="148.0" layoutY="44.0" majorTickUnit="0.5" max="1.0" min="-1.0" minorTickCount="10" prefHeight="16.0" prefWidth="415.0" showTickMarks="true" snapToTicks="true" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="0.0" />
<Label layoutX="14.0" layoutY="72.0" text="Hue" AnchorPane.leftAnchor="9.0" />
<TextField fx:id="hueValue" layoutX="98.0" layoutY="67.0" prefHeight="26.0" prefWidth="60.0" />
<Slider fx:id="hueSlider" blockIncrement="0.1" layoutX="148.0" layoutY="73.0" majorTickUnit="0.5" max="1.0" min="-1.0" minorTickCount="10" prefHeight="16.0" prefWidth="415.0" showTickMarks="true" snapToTicks="true" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="0.0" />
<Label layoutX="14.0" layoutY="101.0" text="Saturation" AnchorPane.leftAnchor="9.0" />
<TextField fx:id="saturationValue" layoutX="98.0" layoutY="96.0" prefHeight="26.0" prefWidth="60.0" />
<Slider fx:id="saturationSlider" blockIncrement="0.1" layoutX="148.0" layoutY="102.0" majorTickUnit="0.5" max="1.0" min="-1.0" minorTickCount="10" prefHeight="16.0" prefWidth="415.0" showTickMarks="true" snapToTicks="true" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="0.0" />
<Label layoutX="9.0" layoutY="130.0" text="Crop Top (px)" />
<TextField fx:id="cropTopValue" layoutX="98.0" layoutY="125.0" prefHeight="26.0" prefWidth="60.0" text="0" />
<Label layoutX="168.0" layoutY="130.0" text="Left" />
<TextField fx:id="cropLeftValue" layoutX="196.0" layoutY="125.0" prefHeight="26.0" prefWidth="60.0" text="0" />
<Label layoutX="266.0" layoutY="130.0" text="Bottom" />
<TextField fx:id="cropBottomValue" layoutX="315.0" layoutY="125.0" prefHeight="26.0" prefWidth="60.0" />
<Label layoutX="385.0" layoutY="130.0" text="Right" />
<TextField fx:id="cropRightValue" layoutX="422.0" layoutY="125.0" prefHeight="26.0" prefWidth="60.0" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab text="Diffusion Coefficients">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="175.0" prefWidth="572.0">
<children>
<GridPane layoutX="14.0" layoutY="14.0" prefHeight="110.0" prefWidth="564.0" AnchorPane.leftAnchor="4.0" AnchorPane.rightAnchor="4.0" AnchorPane.topAnchor="9.0">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="16.0" prefWidth="17.0" text="X" textAlignment="CENTER" GridPane.columnIndex="2" GridPane.halignment="CENTER" />
<TextField fx:id="coefficientValue30" text="0" GridPane.columnIndex="3">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue40" text="0" GridPane.columnIndex="4">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue01" text="0" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue11" text="0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue21" text="0" GridPane.columnIndex="2" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue31" text="0" GridPane.columnIndex="3" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue41" text="0" GridPane.columnIndex="4" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue02" text="0" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue12" text="0" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue22" text="0" GridPane.columnIndex="2" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue32" text="0" GridPane.columnIndex="3" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="coefficientValue42" text="0" GridPane.columnIndex="4" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<Separator prefWidth="200.0" />
<Separator prefWidth="200.0" GridPane.columnIndex="1" />
</children>
</GridPane>
<SplitMenuButton layoutX="430.0" layoutY="120.0" mnemonicParsing="false" text="Select preset..." AnchorPane.bottomAnchor="13.0" AnchorPane.rightAnchor="9.0">
<items>
<MenuItem mnemonicParsing="false" onAction="#configureFloydSteinbergPreset" text="Floyd-Steinberg" />
<MenuItem mnemonicParsing="false" onAction="#configureFastFloydSteinbergPreset" text="Fast Floyd-Steinberg" />
<MenuItem mnemonicParsing="false" onAction="#configureJarvisJudiceNinkePreset" text="Jarvis-Judice-Ninke" />
<MenuItem mnemonicParsing="false" onAction="#configureStuckiPreset" text="Stucki" />
<MenuItem mnemonicParsing="false" onAction="#configureAtkinsonPreset" text="Atkinson" />
<MenuItem mnemonicParsing="false" onAction="#configureBurkesPreset" text="Burkes" />
<MenuItem mnemonicParsing="false" onAction="#configureSierraPreset" text="Sierra" />
<MenuItem mnemonicParsing="false" onAction="#configureTwoRowSierraPreset" text="Two-Row Sierra" />
<MenuItem mnemonicParsing="false" onAction="#configureSierraLitePreset" text="Sierra Lite" />
</items>
</SplitMenuButton>
<TextField fx:id="divisorValue" layoutX="375.0" layoutY="131.0" prefHeight="26.0" prefWidth="46.0" text="1" AnchorPane.rightAnchor="161.0" />
<Label layoutX="326.0" layoutY="136.0" text="Divisor" AnchorPane.rightAnchor="212.0" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab text="Output">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="13.0" prefHeight="16.0" prefWidth="53.0" text="Width" textAlignment="RIGHT" />
<TextField fx:id="outputWidthValue" layoutX="69.0" layoutY="8.0" prefHeight="16.0" prefWidth="122.0" promptText="Width (in pixels)" />
<Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="44.0" prefHeight="16.0" prefWidth="53.0" text="Height" textAlignment="RIGHT" />
<TextField fx:id="outputHeightValue" layoutX="69.0" layoutY="39.0" prefHeight="16.0" prefWidth="122.0" promptText="Height (in pixels)" />
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
<Button layoutX="14.0" layoutY="438.0" mnemonicParsing="false" onAction="#performQuantizePass" prefHeight="26.0" prefWidth="141.0" text="Quantize Pass" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" />
<Button layoutX="162.0" layoutY="442.0" mnemonicParsing="false" onAction="#performDiffusionPass" text="Error Diffusion Pass" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="162.0" />
<Button layoutX="482.0" layoutY="412.0" mnemonicParsing="false" onAction="#performOK" text="OK" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="81.0" />
<Button layoutX="526.0" layoutY="412.0" mnemonicParsing="false" onAction="#performCancel" text="Cancel" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
</children>
</AnchorPane>

View File

@ -6,14 +6,14 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="tilesTab" minHeight="0.0" minWidth="0.0" prefHeight="420.0" prefWidth="677.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.badvision.outlaweditor.ui.impl.ImageEditorTabControllerImpl">
<AnchorPane id="tilesTab" minHeight="0.0" minWidth="0.0" prefHeight="420.0" prefWidth="677.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.badvision.outlaweditor.ui.impl.ImageEditorTabControllerImpl">
<children>
<VBox prefHeight="420.0000999999975" prefWidth="677.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<ToolBar prefWidth="686.0">
<items>
<Label text="Image:" />
<ComboBox id="tileSelect" fx:id="imageSelector" onAction="#onImageSelected"/>
<ComboBox id="tileSelect" fx:id="imageSelector" onAction="#onImageSelected" />
<Button mnemonicParsing="false" onAction="#onImageCreatePressed" text="Create new" />
<Button mnemonicParsing="false" onAction="#onImageClonePressed" text="Clone" />
<Button mnemonicParsing="false" onAction="#onImageExportPressed" text="Export" />
@ -42,22 +42,31 @@
<children>
<Label layoutX="4.0" layoutY="14.0" text="Name" />
<TextField id="" fx:id="imageNameField" layoutX="53.0" layoutY="11.0" prefWidth="147.0" />
<Label layoutX="4.0" layoutY="36.0" text="Category" />
<TextField id="tileCategoryField" fx:id="imageCategoryField" layoutX="74.0" layoutY="33.0" prefWidth="126.0" />
<TextField fx:id="imageWidthField" layoutY="55.0" prefWidth="145.0" AnchorPane.leftAnchor="53.0" AnchorPane.rightAnchor="0.0" />
<Label layoutX="4.0" layoutY="58.0" text="Width" />
<TextField id="imageWidthField" fx:id="imageHeightField" layoutX="53.0" layoutY="77.0" prefWidth="147.0" />
<Label layoutX="4.0" layoutY="83.0" text="Height" />
<Label layoutX="4.0" layoutY="44.0" text="Category" />
<TextField id="tileCategoryField" fx:id="imageCategoryField" layoutX="74.0" layoutY="41.0" prefWidth="126.0" />
<TextField fx:id="imageWidthField" layoutX="53.0" layoutY="71.0" prefWidth="145.0" AnchorPane.leftAnchor="53.0" AnchorPane.rightAnchor="0.0" />
<Label layoutX="4.0" layoutY="74.0" text="Width" />
<TextField id="imageWidthField" fx:id="imageHeightField" layoutX="53.0" layoutY="101.0" prefWidth="147.0" />
<Label layoutX="4.0" layoutY="107.0" text="Height" />
</children>
</AnchorPane>
<AnchorPane id="mapEditorAnchorPane" fx:id="imageEditorAnchorPane" prefHeight="389.0" prefWidth="477.0" HBox.hgrow="ALWAYS">
<children>
<Button layoutX="236.0" mnemonicParsing="false" onAction="#scrollImageUp" styleClass="moveButton" text="Up" AnchorPane.topAnchor="5.0" />
<Button layoutY="185.0" mnemonicParsing="false" onAction="#scrollImageLeft" rotate="270.0" styleClass="moveButton" text="Left" AnchorPane.leftAnchor="-20.0" />
<Button layoutX="236.0" mnemonicParsing="false" onAction="#scrollImageDown" rotate="180.0" styleClass="moveButton" text="Down" AnchorPane.bottomAnchor="5.0" />
<Button layoutY="175.0" mnemonicParsing="false" onAction="#scrollImageRight" rotate="90.0" styleClass="moveButton" text="Right" AnchorPane.rightAnchor="-15.0" />
<Button mnemonicParsing="false" onAction="#imageZoomIn" styleClass="zoomInButton" text="+" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="5.0" />
<Button mnemonicParsing="false" onAction="#imageZoomOut" prefHeight="23.999908447265625" styleClass="zoomOutButton" text="-" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="30.0" />
<ScrollPane fx:id="imageEditorScrollPane" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<Group>
<children>
<Group fx:id="imageEditorZoomGroup">
<children>
<AnchorPane fx:id="imageEditorScrollAnchorPane" prefHeight="354.0" prefWidth="446.0" />
</children>
</Group>
</children>
</Group>
</content>
</ScrollPane>
<Button layoutX="433.0" layoutY="5.0" mnemonicParsing="false" onAction="#imageZoomIn" styleClass="zoomInButton" text="+" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="5.0" />
<Button layoutX="435.0" layoutY="37.0" mnemonicParsing="false" onAction="#imageZoomOut" prefHeight="23.999908447265625" styleClass="zoomOutButton" text="-" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="37.0" />
</children>
</AnchorPane>
</children>
@ -65,4 +74,4 @@
</children>
</VBox>
</children>
</AnchorPane>
</AnchorPane>

View File

@ -0,0 +1,3 @@
.mainFxmlClass {
}

View File

@ -0,0 +1,216 @@
package org.badvision.outlaweditor.test;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import org.badvision.outlaweditor.apple.AppleTileRenderer;
import org.badvision.outlaweditor.apple.ImageDitherEngine;
import org.badvision.outlaweditor.apple.Palette;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.Rule;
/**
*
* @author blurry
*/
public class ImageDitheringTest {
public ImageDitheringTest() {
}
ImageDitherEngine hgrDither, dhgrDither;
@Rule
public JavaFXThreadingRule javafxRule = new JavaFXThreadingRule();
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
AppleTileRenderer.useSolidPalette = false;
hgrDither = new ImageDitherEngine(org.badvision.outlaweditor.Platform.AppleII);
hgrDither.setOutputDimensions(40, 192);
dhgrDither = new ImageDitherEngine(org.badvision.outlaweditor.Platform.AppleII_DHGR);
dhgrDither.setOutputDimensions(80, 192);
}
@After
public void tearDown() {
}
@Test
public void colorDiffTest() {
int[] white = {255, 255, 255};
int[] black = {0, 0, 0};
int[] gray = {128, 128, 128};
assertEquals(0, Palette.distance(white, white), 0);
assertEquals(0, Palette.distance(black, black), 0);
assertEquals(0, Palette.distance(gray, gray), 0);
double midDist1 = Palette.distance(white, gray);
double midDist2 = Palette.distance(black, gray);
assertEquals(midDist1, midDist2, 3.0);
double maxDist = Palette.distance(white, black);
assertEquals(maxDist, midDist1 + midDist2, 0.01);
assertEquals(255.0 * Math.sqrt(3.0), maxDist, 0.01);
}
@Test
public void blackTestHGR() {
testSolidColor(Color.BLACK, hgrDither, 0.0);
}
@Test
public void blackTestDHGR() {
testSolidColor(Color.BLACK, dhgrDither, 0.0);
}
@Test
public void whiteTestHGR() {
testSolidColor(Color.WHITE, hgrDither, 3.0);
}
@Test
public void whiteTestDHGR() {
testSolidColor(Color.WHITE, dhgrDither, 3.0);
}
@Test
public void grayHGRTest() {
testSolidColor(new Color(0.5f, 0.5f, 0.5f, 1.0f), hgrDither, 100.0);
}
@Test
public void grayDHGRTest() {
testSolidColor(new Color(0.5f, 0.5f, 0.5f, 1.0f), dhgrDither, 100.0);
}
@Test
public void redHGRTest() {
testSolidColor(new Color(1f, 0f, 0f, 1.0f), hgrDither, 115.0);
}
@Test
public void redDHGRTest() {
testSolidColor(new Color(1f, 0f, 0f, 1.0f), dhgrDither, 100.0);
}
@Test
public void greenHGRTest() {
testSolidColor(new Color(0f, 1f, 0f, 1.0f), hgrDither, 100.0);
}
@Test
public void greenDHGRTest() {
testSolidColor(new Color(0f, 1f, 0f, 1.0f), dhgrDither, 100.0);
}
@Test
public void blueHGRTest() {
testSolidColor(new Color(0f, 0f, 1f, 1.0f), hgrDither, 162.0);
}
@Test
public void blueDHGRTest() {
testSolidColor(new Color(0f, 0f, 1f, 1.0f), dhgrDither, 100.0);
}
private void testSolidColor(Color color, ImageDitherEngine engine, Double maxDelta) {
WritableImage source = new WritableImage(560, 192);
fillColor(source, color);
WritableImage converted = getTestConversion(engine, source);
assertLowError(source, converted, 16, maxDelta);
}
public void assertExactImage(Image img1, Image img2) throws AssertionError {
for (int x = 0; x < img1.getWidth(); x++) {
for (int y = 0; y < img1.getHeight(); y++) {
int col1 = img1.getPixelReader().getArgb(x, y) & 0x0FFFFFF;
int col2 = img2.getPixelReader().getArgb(x, y) & 0x0FFFFFF;
if (col1 != col2) {
throw new AssertionError("Pixels are not the same color at " + x + "," + y + "; (" + Integer.toHexString(col1) + " vs " + Integer.toHexString(col2));
}
}
}
}
public void assertLowError(Image img1, Image img2, int gridSize, double maxError) throws AssertionError {
double error = getAverageImageError(img1, img2, gridSize);
if (error > maxError) {
throw new AssertionError("Average error is greater than threshold: " + error + " (max is " + maxError + ")");
}
}
public void assertHighError(Image img1, Image img2, int gridSize, double minError) throws AssertionError {
double error = getAverageImageError(img1, img2, gridSize);
if (error < minError) {
throw new AssertionError("Average error is lower than threshold: " + error + " (min is " + minError + ")");
}
}
// Evaluates a pair of images as a grid of square regions
// Returns the average error value of all regions
public double getAverageImageError(Image img1, Image img2, int gridSize) {
double totalError = 0;
double regionCount = 0;
for (int x = 0; x < img1.getWidth(); x += gridSize) {
int x2 = (int) Math.min(img1.getWidth(), x + gridSize);
for (int y = 0; y < img1.getHeight(); y += gridSize) {
int y2 = (int) Math.min(img1.getHeight(), y + gridSize);
totalError += averageErrorForRegion(img1, img2, x, x2, y, y2);
regionCount++;
}
}
return totalError / regionCount;
}
public double averageErrorForRegion(Image img1, Image img2, int x1, int x2, int y1, int y2) {
int[] col1 = getAverageColor(img1, x1, x2, y1, y2);
int[] col2 = getAverageColor(img2, x1, x2, y1, y2);
return Palette.distance(col1, col2);
}
public int[] getAverageColor(Image img, int x1, int x2, int y1, int y2) {
long[] colors = new long[3];
long pixelCount = 0;
for (int x = x1; x < x2 && x < img.getWidth(); x++) {
for (int y = y1; y < y2 && y < img.getHeight(); y++) {
int color = img.getPixelReader().getArgb(x, y) & 0x0ffffff;
int[] col = Palette.parseIntColor(color);
colors[0] += (long) col[0];
colors[1] += (long) col[1];
colors[2] += (long) col[2];
pixelCount++;
}
}
return new int[]{
(int) (colors[0] / pixelCount),
(int) (colors[1] / pixelCount),
(int) (colors[2] / pixelCount)
};
}
private void configureBrendanDither(ImageDitherEngine ditherEngine) {
int[][] coefficients = new int[][]{
{0, 8, 0}, {0, 16, 4}, {0, 32, 8}, {32, 16, 4}, {24, 8, 0}};
ditherEngine.setCoefficients(coefficients);
ditherEngine.setDivisor(240);
}
private void fillColor(WritableImage img, Color color) {
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
img.getPixelWriter().setColor(x, y, color);
}
}
}
private WritableImage getTestConversion(ImageDitherEngine dither, WritableImage source) {
dither.setSourceImage(source);
configureBrendanDither(dither);
dither.dither(true);
return dither.getPreviewImage();
}
}

View File

@ -0,0 +1,98 @@
package org.badvision.outlaweditor.test;
import java.util.concurrent.CountDownLatch;
import javax.swing.SwingUtilities;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* A JUnit {@link Rule} for running tests on the JavaFX thread and performing
* JavaFX initialization. To include in your test case, add the following code:
*
* <pre>
* {@literal @}Rule
* public JavaFXThreadingRule jfxRule = new JavaFXThreadingRule();
* </pre>
*
* @author Andy Till
*
*/
public class JavaFXThreadingRule implements TestRule {
/**
* Flag for setting up the JavaFX, we only need to do this once for all tests.
*/
private static boolean jfxIsSetup;
@Override
public Statement apply(Statement statement, Description description) {
return new OnJFXThreadStatement(statement);
}
private static class OnJFXThreadStatement extends Statement {
private final Statement statement;
public OnJFXThreadStatement(Statement aStatement) {
statement = aStatement;
}
private Throwable rethrownException = null;
@Override
public void evaluate() throws Throwable {
if(!jfxIsSetup) {
setupJavaFX();
jfxIsSetup = true;
}
final CountDownLatch countDownLatch = new CountDownLatch(1);
Platform.runLater(() -> {
try {
statement.evaluate();
} catch (Throwable e) {
rethrownException = e;
}
countDownLatch.countDown();
});
countDownLatch.await();
// if an exception was thrown by the statement during evaluation,
// then re-throw it to fail the test
if(rethrownException != null) {
throw rethrownException;
}
}
protected void setupJavaFX() throws InterruptedException {
long timeMillis = System.currentTimeMillis();
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(() -> {
// initializes JavaFX environment
new JFXPanel();
latch.countDown();
});
System.out.println("javafx initialising...");
latch.await();
System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms");
}
}
}

View File

@ -176,15 +176,6 @@ void idglobal_size(int type, int size, int constsize)
else if (size)
emit_data(0, 0, 0, size);
}
int idlocal_size(void)
{
return (localsize);
}
void idlocal_reset(void)
{
locals = 0;
localsize = 2;
}
int id_tag(char *name, int len)
{
int i;
@ -397,10 +388,13 @@ void emit_trailer(void)
}
void emit_moddep(char *name, int len)
{
if (name)
emit_dci(name, len);
else
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
if (outflags & MODULE)
{
if (name)
emit_dci(name, len);
else
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
}
}
void emit_sysflags(int val)
{
@ -511,6 +505,8 @@ void emit_def(char *name, int is_bytecode)
if (is_bytecode)
printf("\tJSR\tINTERP\n");
}
locals = 0;
localsize = 0;
}
void emit_codetag(int tag)
{
@ -672,9 +668,9 @@ void emit_ical(void)
{
printf("\t%s\t$56\t\t\t; ICAL\n", DB);
}
void emit_leave(int framesize)
void emit_leave(void)
{
if (framesize > 2)
if (localsize)
printf("\t%s\t$5A\t\t\t; LEAVE\n", DB);
else
printf("\t%s\t$5C\t\t\t; RET\n", DB);
@ -683,10 +679,10 @@ void emit_ret(void)
{
printf("\t%s\t$5C\t\t\t; RET\n", DB);
}
void emit_enter(int framesize, int cparams)
void emit_enter(int cparams)
{
if (framesize > 2)
printf("\t%s\t$58,$%02X,$%02X\t\t; ENTER\t%d,%d\n", DB, framesize, cparams, framesize, cparams);
if (localsize)
printf("\t%s\t$58,$%02X,$%02X\t\t; ENTER\t%d,%d\n", DB, localsize, cparams, localsize, cparams);
}
void emit_start(void)
{

View File

@ -51,9 +51,9 @@ void emit_dup(void);
void emit_push(void);
void emit_pull(void);
void emit_drop(void);
void emit_leave(int framesize);
void emit_leave(void);
void emit_ret(void);
void emit_enter(int framesize, int cparams);
void emit_enter(int cparams);
void emit_start(void);
void emit_rld(void);
void emit_esd(void);

View File

@ -22,28 +22,28 @@ t_token keywords[] = {
ENDCASE_TOKEN, 'W', 'E', 'N', 'D',
FOR_TOKEN, 'F', 'O', 'R',
TO_TOKEN, 'T', 'O',
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
STEP_TOKEN, 'S', 'T', 'E', 'P',
NEXT_TOKEN, 'N', 'E', 'X', 'T',
REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T',
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
ASM_TOKEN, 'A', 'S', 'M',
DEF_TOKEN, 'D', 'E', 'F',
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
END_TOKEN, 'E', 'N', 'D',
EXIT_TOKEN, 'E', 'X', 'I', 'T',
DONE_TOKEN, 'D', 'O', 'N', 'E',
LOGIC_NOT_TOKEN, 'N', 'O', 'T',
LOGIC_AND_TOKEN, 'A', 'N', 'D',
LOGIC_OR_TOKEN, 'O', 'R',
LOGIC_OR_TOKEN, 'O', 'R',
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
WORD_TOKEN, 'W', 'O', 'R', 'D',
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
STRUC_TOKEN, 'S', 'T', 'R', 'U', 'C',
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
EOL_TOKEN
};
@ -376,7 +376,6 @@ int next_line(void)
{
statement = ++scanpos;
scantoken = EOL_TOKEN;
scan();
}
else
{
@ -385,8 +384,7 @@ int next_line(void)
statement = inputline;
scanpos = inputline;
scantoken = EOL_TOKEN;
scan();
printf("; %03d: %s\n", lineno, inputline);
}
return (1);
return (scan());
}

View File

@ -256,7 +256,7 @@ int parse_value(int rvalue)
}
else if (scantoken == CLOSE_PAREN_TOKEN)
{
// type |= WORD_TYPE;
// type |= WORD_TYPE;
emit_value = 1;
}
else
@ -355,8 +355,8 @@ int parse_value(int rvalue)
}
else
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
emit_value = 1;
}
emit_value = 1;
type &= ~(VAR_TYPE | ADDR_TYPE);
type |= WORD_TYPE;
scantoken = scantoken == PTRB_TOKEN ? DOT_TOKEN : COLON_TOKEN;
@ -387,6 +387,7 @@ int parse_value(int rvalue)
else // FUNC_TYPE
{
emit_globaladdr(value, elem_offset, type);
elem_offset = 0;
emit_value = 1;
}
}
@ -416,9 +417,10 @@ int parse_value(int rvalue)
}
else if (type & CONST_TYPE)
{
emit_const(value);
emit_const(value + elem_offset);
}
emit_value = 1;
elem_offset = 0;
emit_value = 1;
}
while (parse_expr())
{
@ -442,7 +444,7 @@ int parse_value(int rvalue)
parse_error("Invalid member offset");
return (0);
}
type = elem_type; //(type & ~(ADDR_TYPE | CONST_TYPE)) | elem_type;
type = elem_type;
break;
case OPEN_PAREN_TOKEN:
/*
@ -869,7 +871,7 @@ int parse_stmnt(void)
emit_drop();
if (!parse_expr())
emit_const(0);
emit_leave(idlocal_size());
emit_leave();
}
else
{
@ -983,7 +985,18 @@ int parse_var(int type)
int consttype, constsize, arraysize, idlen = 0;
long size = 1;
if (scan() == ID_TOKEN)
if (scan() == OPEN_BRACKET_TOKEN)
{
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
scan();
}
if (scantoken == ID_TOKEN)
{
idstr = tokenstr;
idlen = tokenlen;
@ -1039,6 +1052,65 @@ int parse_var(int type)
id_add(idstr, idlen, type, size);
return (1);
}
int parse_struc(void)
{
long size;
int type, constsize, offset = 0;
char *idstr, strucid[80];
int idlen = 0, struclen = 0;
if (scan() == ID_TOKEN)
{
struclen = tokenlen;
for (idlen = 0; idlen < struclen; idlen++)
strucid[idlen] = tokenstr[idlen];
}
while (next_line() == BYTE_TOKEN || scantoken == WORD_TOKEN)
{
size = 1;
type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE;
if (scan() == OPEN_BRACKET_TOKEN)
{
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
scan();
}
do {
idlen = 0;
if (scantoken == ID_TOKEN)
{
idstr = tokenstr;
idlen = tokenlen;
if (scan() == OPEN_BRACKET_TOKEN)
{
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
scan();
}
}
if (type & WORD_TYPE)
size *= 2;
if (idlen)
idconst_add(idstr, idlen, offset);
offset += size;
} while (scantoken == COMMA_TOKEN);
if (scantoken != EOL_TOKEN && scantoken != COMMENT_TOKEN)
return (0);
}
if (struclen)
idconst_add(strucid, struclen, offset);
return (scantoken == END_TOKEN);
}
int parse_vars(int type)
{
long value;
@ -1080,6 +1152,13 @@ int parse_vars(int type)
}
idconst_add(idstr, idlen, value);
break;
case STRUC_TOKEN:
if (!parse_struc())
{
parse_error("Bad structure definition");
return (0);
}
break;
case EXPORT_TOKEN:
if (type & (EXTERN_TYPE | LOCAL_TYPE))
{
@ -1224,7 +1303,6 @@ int parse_defs(void)
emit_idfunc(func_tag, type, tokenstr);
emit_def(tokenstr, 1);
tokenstr[tokenlen] = c;
idlocal_reset();
if (scan() == OPEN_PAREN_TOKEN)
{
do
@ -1244,7 +1322,7 @@ int parse_defs(void)
scan();
}
while (parse_vars(LOCAL_TYPE)) next_line();
emit_enter(idlocal_size(), cfnparms);
emit_enter(cfnparms);
prevstmnt = 0;
while (parse_stmnt()) next_line();
infunc = 0;
@ -1261,7 +1339,7 @@ int parse_defs(void)
if (prevstmnt != RETURN_TOKEN)
{
emit_const(0);
emit_leave(idlocal_size());
emit_leave();
}
return (1);
}

View File

@ -28,7 +28,8 @@ int show_state = 0;
#define MEM_SIZE 65536
byte mem_data[MEM_SIZE];
uword sp = 0x01FE, fp = 0xFFFF, heap = 0x0200, deftbl = DEF_CALL, lastdef = DEF_CALL;
#define PHA(b) (mem_data[sp--]=(b))
#define PLA() (mem_data[++sp])
#define EVAL_STACKSZ 16
#define PUSH(v) (*(--esp))=(v)
#define POP ((word)(*(esp++)))
@ -656,8 +657,8 @@ void interp(code *ip)
break;
case 0x34: // PUSH : TOSP = TOS
val = POP;
mem_data[sp--] = val >> 8;
mem_data[sp--] = val;
PHA(val >> 8);
PHA(val);
break;
case 0x36: // PULL : TOS = TOSP
PUSH(mem_data[sp] | (mem_data[sp + 1] << 8));
@ -756,8 +757,7 @@ void interp(code *ip)
case 0x58: // ENTER : NEW FRAME, FOREACH PARAM LOCALVAR = TOS
frmsz = BYTE_PTR(ip);
ip++;
mem_data[fp - frmsz] = fp;
mem_data[fp - frmsz + 1] = fp >> 8;
PHA(frmsz);
if (show_state)
printf("< $%04X: $%04X > ", fp - frmsz, fp);
fp -= frmsz;
@ -766,16 +766,16 @@ void interp(code *ip)
while (parmcnt--)
{
val = POP;
mem_data[fp + parmcnt * 2 + 2] = val;
mem_data[fp + parmcnt * 2 + 3] = val >> 8;
mem_data[fp + parmcnt * 2 + 0] = val;
mem_data[fp + parmcnt * 2 + 1] = val >> 8;
if (show_state)
printf("< $%04X: $%04X > ", fp + parmcnt * 2 + 2, mem_data[fp + parmcnt * 2 + 2] | (mem_data[fp + parmcnt * 2 + 3] >> 8));
printf("< $%04X: $%04X > ", fp + parmcnt * 2 + 0, mem_data[fp + parmcnt * 2 + 0] | (mem_data[fp + parmcnt * 2 + 1] >> 8));
}
if (show_state)
printf("\n");
break;
case 0x5A: // LEAVE : DEL FRAME, IP = TOFP
fp = mem_data[fp] | (mem_data[fp + 1] << 8);
fp += PLA();
case 0x5C: // RET : IP = TOFP
return;
case 0x5E: // ???

View File

@ -179,11 +179,14 @@ OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
;*
;* ENTER INTO BYTECODE INTERPRETER
;*
DINTERP PLA
DINTRP PLA
CLC
ADC #$01
STA IPL
PLA
ADC #$00
STA IPH
LDY #$01
LDY #$00
LDA #>OPTBL
STA OPPAGE
JMP FETCHOP
@ -255,7 +258,7 @@ CMDEXEC = *
;
; INSTALL PAGE 3 VECTORS
;
LDY #$11
LDY #$12
- LDA PAGE3,Y
STA INTERP,Y
DEY
@ -331,7 +334,7 @@ PAGE3 = *
;*
!PSEUDOPC $03D0 {
BIT LCRDEN+LCBNK2 ; $03D0 - DIRECT INTERP ENTRY
JMP DINTERP
JMP DINTRP
BIT LCRDEN+LCBNK2 ; $03D6 - INDIRECT INTERP ENTRY
JMP IINTRP
BIT LCRDEN+LCBNK2 ; $03DC - INDIRECT INTERPX ENTRY
@ -351,7 +354,7 @@ OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
!WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E
!WORD LNOT,LOR,LAND,LA,LLA,CB,CW,SWAP ; 20 22 24 26 28 2A 2C 2E
!WORD DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
!WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU; 40 42 44 46 48 4A 4C 4E
!WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
!WORD BRNCH,IBRNCH,CALLX,ICALX,ENTERX,LEAVEX,RETX,NEXTOP; 50 52 54 56 58 5A 5C 5E
!WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLBX,DLWX ; 60 62 64 66 68 6A 6C 6E
!WORD SBX,SWX,SLBX,SLWX,SABX,SAWX,DABX,DAWX ; 70 72 74 76 78 7A 7C 7E
@ -398,28 +401,30 @@ IDXW LDA ESTKL,X
;*
MUL STY IPY
LDY #$10
LDA #$00
STA TMPL ; PRODL
STA TMPH ; PRODH
MULLP LSR ESTKH,X ; MULTPLRH
ROR ESTKL,X ; MULTPLRL
BCC +
LDA ESTKL+1,X ; MULTPLNDL
CLC
ADC TMPL ; PRODL
LDA ESTKL+1,X
EOR #$FF
STA TMPL
LDA ESTKH+1,X ; MULTPLNDH
ADC TMPH ; PRODH
LDA ESTKH+1,X
EOR #$FF
STA TMPH
+ ASL ESTKL+1,X ; MULTPLNDL
ROL ESTKH+1,X ; MULTPLNDH
LDA #$00
STA ESTKL+1,X ; PRODL
; STA ESTKH+1,X ; PRODH
MULLP LSR TMPH ; MULTPLRH
ROR TMPL ; MULTPLRL
BCS +
STA ESTKH+1,X ; PRODH
LDA ESTKL,X ; MULTPLNDL
ADC ESTKL+1,X ; PRODL
STA ESTKL+1,X
LDA ESTKH,X ; MULTPLNDH
ADC ESTKH+1,X ; PRODH
+ ASL ESTKL,X ; MULTPLNDL
ROL ESTKH,X ; MULTPLNDH
DEY
BNE MULLP
STA ESTKH+1,X ; PRODH
INX
; LDA TMPH ; PRODH
STA ESTKH,X
LDA TMPL ; PRODL
STA ESTKL,X
LDY IPY
JMP NEXTOP
;*
@ -434,6 +439,10 @@ _NEG LDA #$00
STA ESTKH,X
RTS
_DIV STY IPY
LDY #$11 ; #BITS+1
LDA #$00
STA TMPL ; REMNDRL
STA TMPH ; REMNDRH
LDA ESTKH,X
AND #$80
STA DVSIGN
@ -448,34 +457,28 @@ _DIV STY IPY
INC DVSIGN
BNE _DIV1
+ ORA ESTKL+1,X ; DVDNDL
BNE _DIV1
STA TMPL
STA TMPH
RTS
_DIV1 LDY #$11 ; #BITS+1
LDA #$00
STA TMPL ; REMNDRL
STA TMPH ; REMNDRH
- ASL ESTKL+1,X ; DVDNDL
BEQ _DIVEX
_DIV1 ASL ESTKL+1,X ; DVDNDL
ROL ESTKH+1,X ; DVDNDH
DEY
BCC -
STY ESTKL-1,X
BCC _DIV1
_DIVLP ROL TMPL ; REMNDRL
ROL TMPH ; REMNDRH
LDA TMPL ; REMNDRL
SEC
SBC ESTKL,X ; DVSRL
TAY
CMP ESTKL,X ; DVSRL
LDA TMPH ; REMNDRH
SBC ESTKH,X ; DVSRH
BCC +
STA TMPH ; REMNDRH
STY TMPL ; REMNDRL
+ ROL ESTKL+1,X ; DVDNDL
LDA TMPL ; REMNDRL
SBC ESTKL,X ; DVSRL
STA TMPL ; REMNDRL
SEC
+ ROL ESTKL+1,X ; DVDNDL
ROL ESTKH+1,X ; DVDNDH
DEC ESTKL-1,X
DEY
BNE _DIVLP
_DIVEX INX
LDY IPY
RTS
;*
@ -1439,100 +1442,76 @@ JMPTMP JMP (TMP)
;*
;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT
;*
ENTER +INC_IP
LDA IFPL
PHA
SEC
SBC (IP),Y
STA IFPL
LDA IFPH
PHA
SBC #$00
STA IFPH
+INC_IP
STY IPY
ENTER INY
LDA (IP),Y
PHA ; SAVE ON STACK FOR LEAVE
EOR #$FF
SEC
ADC IFPL
STA IFPL
BCS +
DEC IFPH
+ INY
LDA (IP),Y
BEQ +
ASL
TAY
INY
BEQ +
- LDA ESTKH,X
STA (IFP),Y
DEY
LDA ESTKL,X
STA (IFP),Y
LDA ESTKL,X
INX
DEY
CPY #$01
STA (IFP),Y
BNE -
+ LDY #$01
PLA
STA (IFP),Y
DEY
PLA
STA (IFP),Y
LDY IPY
+ LDY #$02
JMP NEXTOP
;
ENTERX +INC_IP
LDA IFPL
PHA
ENTERX INY
LDA (IP),Y
PHA ; SAVE ON STACK FOR LEAVEX
EOR #$FF
SEC
SBC (IP),Y
ADC IFPL
STA IFPL
LDA IFPH
PHA
SBC #$00
STA IFPH
+INC_IP
STY IPY
BCS +
DEC IFPH
+ INY
LDA (IP),Y
STA ALTRDOFF
BEQ +
ASL
TAY
INY
BEQ +
- LDA ESTKH,X
STA (IFP),Y
DEY
LDA ESTKL,X
STA (IFP),Y
LDA ESTKL,X
INX
DEY
CPY #$01
STA (IFP),Y
BNE -
+ LDY #$01
PLA
STA (IFP),Y
DEY
PLA
STA (IFP),Y
STA ALTRDON
LDY IPY
+ STA ALTRDON
LDY #$02
JMP NEXTOP
;*
;* LEAVE FUNCTION
;*
LEAVE LDY #$01
LDA (IFP),Y
DEY
PHA
LDA (IFP),Y
LEAVE PLA
CLC
ADC IFPL
STA IFPL
PLA
STA IFPH
BCS LIFPH
RTS
LIFPH INC IFPH
RET RTS
;
LEAVEX STA ALTRDOFF
CLI
LDY #$01
LDA (IFP),Y
DEY
PHA
LDA (IFP),Y
STA IFPL
PLA
STA IFPH
CLC
ADC IFPL
STA IFPL
BCS LIFPH
RTS
RETX STA ALTRDOFF
CLI

View File

@ -34,6 +34,4 @@ int id_tag(char *name, int len);
int id_const(char *name, int len);
int id_type(char *name, int len);
void idglobal_size(int type, int size, int constsize);
int idlocal_size(void);
void idlocal_reset(void);
int tag_new(int type);

View File

@ -1,29 +1,36 @@
//
// Include all imported modules and their data/functions.
//
include(stdlib.plh)
include(testlib.plh)
//
// Structure definition.
//
struc mystruc
byte cmd
word param
byte[3]
word data
end
//
// Declare all global variables for this module.
// Note that arrays are declared with prefix []. postfix [], or no [].
// Only arrays with predclared sizes need [ and ], such as "int[3] a".
//
byte hello[] = "Hello, Apple "
byte a1[] = "1"
byte a2[] = "]["
byte a2p[] = "][+"
byte a2e[] = "//e"
byte a2c[] = "//c"
byte a3[] = "///"
word struct[] = 1, 10, 100, 1000, 10000
byte[] hello = "Hello, Apple "
byte[] a1 = "1"
byte[] a2 = "]["
byte[] a2p = "][+"
byte[] a2e = "//e"
byte[] a2c = "//c"
byte[] a3 = "///"
byte[] offsets = "Structure offsets:"
word array[] = 1, 10, 100, 1000, 10000
word ptr
byte spaces[] = " "
byte spaces = " "
//
// Define functions.
//
def tens(start)
word i
i = start
@ -35,7 +42,6 @@ def tens(start)
i = i / 10
until i == 0
end
def ascii
byte i
i = 32
@ -44,7 +50,6 @@ def ascii
i = i + 1
loop
end
def nums(range)
word i
for i = range downto -range step range/10
@ -52,7 +57,6 @@ def nums(range)
putln
next
end
export def main(range)
nums(*range)
tens(*range*10)
@ -83,9 +87,8 @@ export def main(range)
wend
putln
end
ptr=@struct
main(@struct:6)
ptr = @array
main(@array:6)
puti((ptr):6)
putln
puti(ptr=>6)
@ -94,4 +97,14 @@ puti((ptr).6)
putln
puti(ptr->6)
putln
puts(@offsets)
putln
puti(cmd)
putln
puti(param)
putln
puti(data)
putln
puti(mystruc)
putln
done

View File

@ -42,7 +42,7 @@
#define RETURN_TOKEN TOKEN(28)
#define BREAK_TOKEN TOKEN(29)
#define SYSFLAGS_TOKEN TOKEN(30)
#define EXIT_TOKEN TOKEN(31)
#define STRUC_TOKEN TOKEN(31)
#define EVAL_TOKEN TOKEN(32)
/*
* Double operand operators.