mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-12-25 13:29:59 +00:00
Merge branch 'master' of https://github.com/badvision/lawless-legends
This commit is contained in:
commit
bc73588a20
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
"++--++--++--++--++--++--++--",
|
||||
"--++--++--++--++--++--++--++"
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
package org.badvision.outlaweditor.ui;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author blurry
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ImageConversionPostAction {
|
||||
public void storeConvertedImage(byte[] image);
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
219
OutlawEditor/src/main/resources/imageConversionWizard.fxml
Normal file
219
OutlawEditor/src/main/resources/imageConversionWizard.fxml
Normal 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>
|
@ -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>
|
||||
|
@ -0,0 +1,3 @@
|
||||
.mainFxmlClass {
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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: // ???
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user