diff --git a/README.md b/README.md
index 44700344..45d03542 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ If you have any questions or problems, don't hesitate to ask our public [mailing
- **vtm-web-app** HTML5/GWT application
The libGDX backend for GWT is experimental.
+- `./gradlew :vtm-web-app:jettyDraftWar` will run standalone Jetty server at port 8080. See http://localhost:8080/vtm-web-app in your web browser.
## Applications
- VTM is used by many [applications](docs/Applications.md).
diff --git a/build.gradle b/build.gradle
index 434a29db..f10e5c9a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,6 +15,7 @@ allprojects {
ext.androidBuildVersionTools = "25.0.0"
ext.gdxVersion = "1.9.4"
+ ext.gwtVersion = "2.7.0"
if (JavaVersion.current().isJava8Compatible()) {
tasks.withType(Javadoc) {
diff --git a/settings.gradle b/settings.gradle
index f069bcc2..f353fcc6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -10,8 +10,8 @@ include ':vtm-themes'
include ':vtm-gdx'
include ':vtm-desktop'
include ':vtm-android-gdx'
-//include ':vtm-web'
-//include ':vtm-web-app'
+include ':vtm-web'
+include ':vtm-web-app'
//include ':vtm-web-js'
include ':vtm-jeo'
include ':vtm-playground'
diff --git a/vtm-web-app/build.gradle b/vtm-web-app/build.gradle
index 783eeffd..eeb78160 100644
--- a/vtm-web-app/build.gradle
+++ b/vtm-web-app/build.gradle
@@ -5,7 +5,7 @@ buildscript {
maven { url 'http://dl.bintray.com/steffenschaefer/maven' }
}
dependencies {
- classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.5'
+ classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
}
}
@@ -38,7 +38,7 @@ evaluationDependsOn(':vtm-gdx')
evaluationDependsOn(':vtm-web')
gwt {
- gwtVersion = '2.6.1'
+ gwtVersion = project.ext.gwtVersion
modules 'org.oscim.web.VtmWebApp'
superDev {
diff --git a/vtm-web-app/src/org/oscim/web/VtmWebApp.gwt.xml b/vtm-web-app/src/org/oscim/web/VtmWebApp.gwt.xml
index 5b6c922d..6fb47b17 100644
--- a/vtm-web-app/src/org/oscim/web/VtmWebApp.gwt.xml
+++ b/vtm-web-app/src/org/oscim/web/VtmWebApp.gwt.xml
@@ -6,8 +6,6 @@
-
-
@@ -23,4 +21,5 @@
+
diff --git a/vtm-web-app/src/org/oscim/web/client/GwtLauncher.java b/vtm-web-app/src/org/oscim/web/client/GwtLauncher.java
index 3940dd88..e7987f2c 100644
--- a/vtm-web-app/src/org/oscim/web/client/GwtLauncher.java
+++ b/vtm-web-app/src/org/oscim/web/client/GwtLauncher.java
@@ -27,6 +27,8 @@ import org.oscim.gdx.client.MapConfig;
public class GwtLauncher extends GwtApplication {
+ private ApplicationListener applicationListener;
+
@Override
public GwtApplicationConfiguration getConfig() {
@@ -36,7 +38,6 @@ public class GwtLauncher extends GwtApplication {
cfg.canvasId = "map-canvas";
cfg.stencil = true;
- cfg.fps = 120;
return cfg;
}
@@ -45,6 +46,14 @@ public class GwtLauncher extends GwtApplication {
public ApplicationListener getApplicationListener() {
Tile.SIZE = MapConfig.get().getTileSize();
+ if (applicationListener == null) {
+ applicationListener = createApplicationListener();
+ }
+ return applicationListener;
+ }
+
+ @Override
+ public ApplicationListener createApplicationListener() {
return new GwtMap();
}
diff --git a/vtm-web-app/src/org/oscim/web/client/GwtMap.java b/vtm-web-app/src/org/oscim/web/client/GwtMap.java
index 0c52c878..bc1c3285 100644
--- a/vtm-web-app/src/org/oscim/web/client/GwtMap.java
+++ b/vtm-web-app/src/org/oscim/web/client/GwtMap.java
@@ -1,5 +1,6 @@
/*
* Copyright 2013 Hannes Janetzek
+ * Copyright 2016 Izumi Kawashima
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -63,6 +64,7 @@ class GwtMap extends GdxMap {
GdxAssets.init("");
CanvasAdapter.textScale = 0.7f;
+ log.debug("GLAdapter.init");
GLAdapter.init((GL) Gdx.graphics.getGL20());
GLAdapter.GDX_WEBGL_QUIRKS = true;
MapRenderer.setBackgroundColor(0xffffff);
@@ -92,12 +94,18 @@ class GwtMap extends GdxMap {
ts = DefaultSources.STAMEN_TONER.build();
else if ("osm".equals(mapName))
ts = DefaultSources.OPENSTREETMAP.build();
+ else if ("osm-transport".equals(mapName))
+ ts = DefaultSources.OSM_TRANSPORT.build();
else if ("watercolor".equals(mapName))
ts = DefaultSources.STAMEN_WATERCOLOR.build();
- else if ("arcgis-shaded".equals(mapName))
- ts = DefaultSources.ARCGIS_RELIEF.build();
else if ("imagico".equals(mapName))
ts = DefaultSources.IMAGICO_LANDCOVER.build();
+ else if ("ne-landcover".equals(mapName))
+ ts = DefaultSources.NE_LANDCOVER.build();
+ else if ("hikebike".equals(mapName))
+ ts = DefaultSources.HIKEBIKE.build();
+ else if ("hikebike-hillshade".equals(mapName))
+ ts = DefaultSources.HIKEBIKE_HILLSHADE.build();
else
ts = DefaultSources.STAMEN_TONER.build();
diff --git a/vtm-web-js/build.gradle b/vtm-web-js/build.gradle
index 55dd0b58..899350a4 100644
--- a/vtm-web-js/build.gradle
+++ b/vtm-web-js/build.gradle
@@ -5,7 +5,7 @@ buildscript {
maven { url 'http://dl.bintray.com/steffenschaefer/maven' }
}
dependencies {
- classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.5'
+ classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
}
}
@@ -39,7 +39,7 @@ evaluationDependsOn(':vtm-gdx')
evaluationDependsOn(':vtm-web')
gwt {
- gwtVersion = '2.6.1'
+ gwtVersion = project.ext.gwtVersion
modules 'org.oscim.web.VtmWebJs'
superDev {
diff --git a/vtm-web-js/src/org/oscim/web/VtmWebJs.gwt.xml b/vtm-web-js/src/org/oscim/web/VtmWebJs.gwt.xml
index cf963562..7fef4444 100644
--- a/vtm-web-js/src/org/oscim/web/VtmWebJs.gwt.xml
+++ b/vtm-web-js/src/org/oscim/web/VtmWebJs.gwt.xml
@@ -10,8 +10,6 @@
-
-
@@ -25,4 +23,8 @@
+
+
+
+
diff --git a/vtm-web-js/src/org/oscim/web/client/GwtLauncher.java b/vtm-web-js/src/org/oscim/web/client/GwtLauncher.java
index f7b32548..427cb2e9 100644
--- a/vtm-web-js/src/org/oscim/web/client/GwtLauncher.java
+++ b/vtm-web-js/src/org/oscim/web/client/GwtLauncher.java
@@ -28,6 +28,8 @@ import org.timepedia.exporter.client.ExporterUtil;
public class GwtLauncher extends GwtApplication {
+ private ApplicationListener applicationListener;
+
@Override
public void onModuleLoad() {
//GWT.create(GwtGdxMap.class);
@@ -46,7 +48,6 @@ public class GwtLauncher extends GwtApplication {
cfg.canvasId = "map-canvas";
cfg.stencil = true;
- cfg.fps = 120;
return cfg;
}
@@ -55,6 +56,14 @@ public class GwtLauncher extends GwtApplication {
public ApplicationListener getApplicationListener() {
Tile.SIZE = MapConfig.get().getTileSize();
+ if (applicationListener == null) {
+ applicationListener = createApplicationListener();
+ }
+ return applicationListener;
+ }
+
+ @Override
+ public ApplicationListener createApplicationListener() {
return new GwtMap();
}
diff --git a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtApplication.java b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtApplication.java
index 56b5ef4a..3a711f8f 100644
--- a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtApplication.java
+++ b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtApplication.java
@@ -1,12 +1,12 @@
/*******************************************************************************
- * Copyright 2011 See libgdx AUTHORS file.
- *
+ * Copyright 2011 See AUTHORS file.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,37 +29,44 @@ import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.backends.gwt.preloader.Preloader;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderCallback;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderState;
-import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Clipboard;
-import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.TimeUtils;
+import com.google.gwt.animation.client.AnimationScheduler;
+import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.user.client.Timer;
+import com.google.gwt.dom.client.CanvasElement;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.user.client.ui.InlineHTML;
+import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.SimplePanel;
+import com.google.gwt.user.client.ui.TextArea;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of an {@link Application} based on GWT. Clients have to
- * override {@link #getConfig()} and {@link #getApplicationListener()}. Clients
- * can override the default loading screen via {@link #getPreloaderCallback()}
- * and implement any loading screen drawing via GWT widgets.
- *
- * @author mzechner
- */
+/** Implementation of an {@link Application} based on GWT. Clients have to override {@link #getConfig()} and
+ * {@link #createApplicationListener()}. Clients can override the default loading screen via
+ * {@link #getPreloaderCallback()} and implement any loading screen drawing via GWT widgets.
+ * @author mzechner */
public abstract class GwtApplication implements EntryPoint, Application {
- private final static Logger log = LoggerFactory.getLogger(GwtApplication.class);
-
private ApplicationListener listener;
- private GwtApplicationConfiguration config;
- private GwtGraphics graphics;
+ GwtApplicationConfiguration config;
+ GwtGraphics graphics;
private GwtInput input;
private GwtNet net;
+ private Panel root = null;
+ private TextArea log = null;
private int logLevel = LOG_ERROR;
private Array runnables = new Array();
private Array runnablesHelper = new Array();
@@ -69,55 +76,104 @@ public abstract class GwtApplication implements EntryPoint, Application {
Preloader preloader;
private static AgentInfo agentInfo;
private ObjectMap prefs = new ObjectMap();
+ private Clipboard clipboard;
+ LoadingListener loadingListener;
- /**
- * @return the configuration for the {@link GwtApplication}.
- */
- public abstract GwtApplicationConfiguration getConfig();
+ /** @return the configuration for the {@link GwtApplication}. */
+ public abstract GwtApplicationConfiguration getConfig ();
- public String getPreloaderBaseURL() {
+
+ public String getPreloaderBaseURL()
+ {
return GWT.getHostPageBaseURL() + "assets/";
}
@Override
- public void onModuleLoad() {
+ public ApplicationListener getApplicationListener() {
+ return listener;
+ }
+
+ public abstract ApplicationListener createApplicationListener();
+
+ @Override
+ public void onModuleLoad () {
GwtApplication.agentInfo = computeAgentInfo();
- this.listener = getApplicationListener();
+ this.listener = createApplicationListener();
this.config = getConfig();
+ this.log = config.log;
+
+ addEventListeners();
+
+ if (config.rootPanel != null) {
+ this.root = config.rootPanel;
+ } else {
+ Element element = Document.get().getElementById("embed-" + GWT.getModuleName());
+ if (element == null) {
+ VerticalPanel panel = new VerticalPanel();
+ panel.setWidth("" + config.width + "px");
+ panel.setHeight("" + config.height + "px");
+ panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
+ panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
+ RootPanel.get().add(panel);
+ RootPanel.get().setWidth("" + config.width + "px");
+ RootPanel.get().setHeight("" + config.height + "px");
+ this.root = panel;
+ } else {
+ VerticalPanel panel = new VerticalPanel();
+ panel.setWidth("" + config.width + "px");
+ panel.setHeight("" + config.height + "px");
+ panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
+ panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
+ element.appendChild(panel.getElement());
+ root = panel;
+ }
+ }
final PreloaderCallback callback = getPreloaderCallback();
preloader = createPreloader();
preloader.preload("assets.txt", new PreloaderCallback() {
@Override
- public void error(String file) {
+ public void error (String file) {
callback.error(file);
}
@Override
- public void update(PreloaderState state) {
+ public void update (PreloaderState state) {
callback.update(state);
if (state.hasEnded()) {
- //getRootPanel().clear();
+ getRootPanel().clear();
+ if(loadingListener != null)
+ loadingListener.beforeSetup();
setupLoop();
+ if(loadingListener != null)
+ loadingListener.afterSetup();
}
}
});
}
- void setupLoop() {
- Gdx.app = this;
+ /**
+ * Override this method to return a custom widget informing the that their browser lacks support of WebGL.
+ *
+ * @return Widget to display when WebGL is not supported.
+ */
+ public Widget getNoWebGLSupportWidget() {
+ return new Label("Sorry, your browser doesn't seem to support WebGL");
+ }
+
+ void setupLoop () {
// setup modules
try {
- graphics = new GwtGraphics(null, config);
+ graphics = new GwtGraphics(root, config);
} catch (Throwable e) {
- error("GwtApplication", "exception: " + e.getMessage(), e);
- //root.clear();
- //root.add(new Label("Sorry, your browser doesn't seem to support WebGL"));
+ root.clear();
+ root.add(getNoWebGLSupportWidget());
return;
}
lastWidth = graphics.getWidth();
lastHeight = graphics.getHeight();
Gdx.app = this;
+ Gdx.audio = new GwtAudio();
Gdx.graphics = graphics;
Gdx.gl20 = graphics.getGL20();
Gdx.gl = Gdx.gl20;
@@ -126,6 +182,8 @@ public abstract class GwtApplication implements EntryPoint, Application {
Gdx.input = this.input;
this.net = new GwtNet();
Gdx.net = this.net;
+ this.clipboard = new GwtClipboard();
+ updateLogLabelSize();
// tell listener about app creation
try {
@@ -137,26 +195,21 @@ public abstract class GwtApplication implements EntryPoint, Application {
throw new RuntimeException(t);
}
- Gdx.gl.glClearColor(1, 1, 1, 1);
- Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
-
- final int frameTime = (int) ((1f / config.fps) * 1000);
-
- // setup rendering timer
- new Timer() {
+ AnimationScheduler.get().requestAnimationFrame(new AnimationCallback() {
@Override
- public void run() {
+ public void execute (double timestamp) {
try {
- mainLoop(this, frameTime);
+ mainLoop();
} catch (Throwable t) {
error("GwtApplication", "exception: " + t.getMessage(), t);
throw new RuntimeException(t);
}
+ AnimationScheduler.get().requestAnimationFrame(this, graphics.canvas);
}
- }.schedule(1);
+ }, graphics.canvas);
}
- void mainLoop(Timer timer, int frameTime) {
+ void mainLoop() {
graphics.update();
if (Gdx.graphics.getWidth() != lastWidth || Gdx.graphics.getHeight() != lastHeight) {
GwtApplication.this.listener.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
@@ -170,17 +223,13 @@ public abstract class GwtApplication implements EntryPoint, Application {
runnablesHelper.get(i).run();
}
runnablesHelper.clear();
+ graphics.frameId++;
listener.render();
- input.justTouched = false;
-
- long now = System.currentTimeMillis();
- int diff = (int) (now - graphics.lastTimeStamp);
- diff = frameTime - diff;
- timer.schedule(diff > 5 ? diff : 5);
+ input.reset();
}
- public Panel getRootPanel() {
- throw new GdxRuntimeException("no panel!");
+ public Panel getRootPanel () {
+ return root;
}
long loadStart = TimeUtils.nanoTime();
@@ -189,27 +238,53 @@ public abstract class GwtApplication implements EntryPoint, Application {
return new Preloader(getPreloaderBaseURL());
}
- public PreloaderCallback getPreloaderCallback() {
- return null;
+ public PreloaderCallback getPreloaderCallback () {
+ final Panel preloaderPanel = new VerticalPanel();
+ preloaderPanel.setStyleName("gdx-preloader");
+ final Image logo = new Image(GWT.getModuleBaseURL() + "logo.png");
+ logo.setStyleName("logo");
+ preloaderPanel.add(logo);
+ final Panel meterPanel = new SimplePanel();
+ meterPanel.setStyleName("gdx-meter");
+ meterPanel.addStyleName("red");
+ final InlineHTML meter = new InlineHTML();
+ final Style meterStyle = meter.getElement().getStyle();
+ meterStyle.setWidth(0, Unit.PCT);
+ meterPanel.add(meter);
+ preloaderPanel.add(meterPanel);
+ getRootPanel().add(preloaderPanel);
+ return new PreloaderCallback() {
+
+ @Override
+ public void error (String file) {
+ System.out.println("error: " + file);
+ }
+
+ @Override
+ public void update (PreloaderState state) {
+ meterStyle.setWidth(100f * state.getProgress(), Unit.PCT);
+ }
+
+ };
}
@Override
- public Graphics getGraphics() {
+ public Graphics getGraphics () {
return graphics;
}
@Override
- public Audio getAudio() {
+ public Audio getAudio () {
return Gdx.audio;
}
@Override
- public Input getInput() {
+ public Input getInput () {
return Gdx.input;
}
@Override
- public Files getFiles() {
+ public Files getFiles () {
return Gdx.files;
}
@@ -218,37 +293,107 @@ public abstract class GwtApplication implements EntryPoint, Application {
return Gdx.net;
}
- @Override
- public void log(String tag, String message) {
- log.info("{} : {}", tag, message);
+ private void updateLogLabelSize () {
+ if (log != null) {
+ if (graphics != null) {
+ log.setSize(graphics.getWidth() + "px", "200px");
+ } else {
+ log.setSize("400px", "200px"); // Should not happen at this point, use dummy value
+ }
+ }
+ }
+
+ private void checkLogLabel () {
+ if (log == null) {
+ log = new TextArea();
+
+ // It's possible that log functions are called
+ // before the app is initialized. E.g. SoundManager can call log functions before the app is initialized.
+ // Since graphics is null, we're getting errors. The log size will be updated later, in case graphics was null
+ if (graphics != null) {
+ log.setSize(graphics.getWidth() + "px", "200px");
+ } else {
+ log.setSize("400px", "200px"); // Dummy value
+ }
+
+ log.setReadOnly(true);
+ root.add(log);
+ }
}
@Override
- public void log(String tag, String message, Throwable exception) {
- log.info("{} : {}\n{}", tag, exception, getStackTrace(exception));
+ public void log (String tag, String message) {
+ if (logLevel >= LOG_INFO) {
+ checkLogLabel();
+ log.setText(log.getText() + "\n" + tag + ": " + message);
+ log.setCursorPos(log.getText().length() - 1);
+ System.out.println(tag + ": " + message);
+ }
}
@Override
- public void error(String tag, String message) {
- log.error("{} : {}", tag, message);
+ public void log (String tag, String message, Throwable exception) {
+ if (logLevel >= LOG_INFO) {
+ checkLogLabel();
+ log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + getMessages(exception) + "\n");
+ log.setCursorPos(log.getText().length() - 1);
+ System.out.println(tag + ": " + message + "\n" + exception.getMessage());
+ System.out.println(getStackTrace(exception));
+ }
}
@Override
- public void error(String tag, String message, Throwable exception) {
- log.error("{} : {}\n{}", tag, message, getStackTrace(exception));
+ public void error (String tag, String message) {
+ if (logLevel >= LOG_ERROR) {
+ checkLogLabel();
+ log.setText(log.getText() + "\n" + tag + ": " + message + "\n");
+ log.setCursorPos(log.getText().length() - 1);
+ System.err.println(tag + ": " + message);
+ }
}
@Override
- public void debug(String tag, String message) {
- log.debug("{} : {}", tag, message);
+ public void error (String tag, String message, Throwable exception) {
+ if (logLevel >= LOG_ERROR) {
+ checkLogLabel();
+ log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + getMessages(exception) + "\n");
+ log.setCursorPos(log.getText().length() - 1);
+ System.err.println(tag + ": " + message + "\n" + exception.getMessage() + "\n");
+ System.out.println(getStackTrace(exception));
+ }
}
@Override
- public void debug(String tag, String message, Throwable exception) {
- log.debug("{} : {}\n{}", tag, message, getStackTrace(exception));
+ public void debug (String tag, String message) {
+ if (logLevel >= LOG_DEBUG) {
+ checkLogLabel();
+ log.setText(log.getText() + "\n" + tag + ": " + message + "\n");
+ log.setCursorPos(log.getText().length() - 1);
+ System.out.println(tag + ": " + message + "\n");
+ }
}
- private String getStackTrace(Throwable e) {
+ @Override
+ public void debug (String tag, String message, Throwable exception) {
+ if (logLevel >= LOG_DEBUG) {
+ checkLogLabel();
+ log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + getMessages(exception) + "\n");
+ log.setCursorPos(log.getText().length() - 1);
+ System.out.println(tag + ": " + message + "\n" + exception.getMessage());
+ System.out.println(getStackTrace(exception));
+ }
+ }
+
+ private String getMessages (Throwable e) {
+ StringBuffer buffer = new StringBuffer();
+ while (e != null) {
+ buffer.append(e.getMessage() + "\n");
+ e = e.getCause();
+ }
+ return buffer.toString();
+ }
+
+ private String getStackTrace (Throwable e) {
StringBuffer buffer = new StringBuffer();
for (StackTraceElement trace : e.getStackTrace()) {
buffer.append(trace.toString() + "\n");
@@ -257,36 +402,37 @@ public abstract class GwtApplication implements EntryPoint, Application {
}
@Override
- public void setLogLevel(int logLevel) {
+ public void setLogLevel (int logLevel) {
+ this.logLevel = logLevel;
}
@Override
public int getLogLevel() {
- return LOG_DEBUG;
+ return logLevel;
}
@Override
- public ApplicationType getType() {
+ public ApplicationType getType () {
return ApplicationType.WebGL;
}
@Override
- public int getVersion() {
+ public int getVersion () {
return 0;
}
@Override
- public long getJavaHeap() {
+ public long getJavaHeap () {
return 0;
}
@Override
- public long getNativeHeap() {
+ public long getNativeHeap () {
return 0;
}
@Override
- public Preferences getPreferences(String name) {
+ public Preferences getPreferences (String name) {
Preferences pref = prefs.get(name);
if (pref == null) {
pref = new GwtPreferences(name);
@@ -296,115 +442,151 @@ public abstract class GwtApplication implements EntryPoint, Application {
}
@Override
- public Clipboard getClipboard() {
- return new Clipboard() {
- @Override
- public String getContents() {
- return null;
- }
-
- @Override
- public void setContents(String content) {
- }
- };
+ public Clipboard getClipboard () {
+ return clipboard;
}
@Override
- public void postRunnable(Runnable runnable) {
+ public void postRunnable (Runnable runnable) {
runnables.add(runnable);
}
@Override
- public void exit() {
+ public void exit () {
}
- /**
- * Contains precomputed information on the user-agent. Useful for dealing
- * with browser and OS behavioral differences. Kindly
- * borrowed from PlayN
- */
- public static AgentInfo agentInfo() {
+ /** Contains precomputed information on the user-agent. Useful for dealing with browser and OS behavioral differences. Kindly
+ * borrowed from PlayN */
+ public static AgentInfo agentInfo () {
return agentInfo;
}
- /**
- * kindly borrowed from PlayN
- **/
- private static native AgentInfo computeAgentInfo() /*-{
- var userAgent = navigator.userAgent.toLowerCase();
- return {
- // browser type flags
- isFirefox : userAgent.indexOf("firefox") != -1,
- isChrome : userAgent.indexOf("chrome") != -1,
- isSafari : userAgent.indexOf("safari") != -1,
- isOpera : userAgent.indexOf("opera") != -1,
- isIE : userAgent.indexOf("msie") != -1,
- // OS type flags
- isMacOS : userAgent.indexOf("mac") != -1,
- isLinux : userAgent.indexOf("linux") != -1,
- isWindows : userAgent.indexOf("win") != -1
- };
- }-*/;
+ /** kindly borrowed from PlayN **/
+ private static native AgentInfo computeAgentInfo () /*-{
+ var userAgent = navigator.userAgent.toLowerCase();
+ return {
+ // browser type flags
+ isFirefox : userAgent.indexOf("firefox") != -1,
+ isChrome : userAgent.indexOf("chrome") != -1,
+ isSafari : userAgent.indexOf("safari") != -1,
+ isOpera : userAgent.indexOf("opera") != -1,
+ isIE : userAgent.indexOf("msie") != -1,
+ // OS type flags
+ isMacOS : userAgent.indexOf("mac") != -1,
+ isLinux : userAgent.indexOf("linux") != -1,
+ isWindows : userAgent.indexOf("win") != -1
+ };
+ }-*/;
- /**
- * Returned by {@link #agentInfo}. Kindly borrowed from PlayN.
- */
+ /** Returned by {@link #agentInfo}. Kindly borrowed from PlayN. */
public static class AgentInfo extends JavaScriptObject {
- public final native boolean isFirefox() /*-{
- return this.isFirefox;
- }-*/;
+ public final native boolean isFirefox () /*-{
+ return this.isFirefox;
+ }-*/;
- public final native boolean isChrome() /*-{
- return this.isChrome;
- }-*/;
+ public final native boolean isChrome () /*-{
+ return this.isChrome;
+ }-*/;
- public final native boolean isSafari() /*-{
- return this.isSafari;
- }-*/;
+ public final native boolean isSafari () /*-{
+ return this.isSafari;
+ }-*/;
- public final native boolean isOpera() /*-{
- return this.isOpera;
- }-*/;
+ public final native boolean isOpera () /*-{
+ return this.isOpera;
+ }-*/;
- public final native boolean isIE() /*-{
- return this.isIE;
- }-*/;
+ public final native boolean isIE () /*-{
+ return this.isIE;
+ }-*/;
- public final native boolean isMacOS() /*-{
- return this.isMacOS;
- }-*/;
+ public final native boolean isMacOS () /*-{
+ return this.isMacOS;
+ }-*/;
- public final native boolean isLinux() /*-{
- return this.isLinux;
- }-*/;
+ public final native boolean isLinux () /*-{
+ return this.isLinux;
+ }-*/;
- public final native boolean isWindows() /*-{
- return this.isWindows;
- }-*/;
+ public final native boolean isWindows () /*-{
+ return this.isWindows;
+ }-*/;
- protected AgentInfo() {
+ protected AgentInfo () {
}
}
- public String getBaseUrl() {
+ public String getBaseUrl () {
return preloader.baseUrl;
}
- public Preloader getPreloader() {
+ public Preloader getPreloader () {
return preloader;
}
+ public CanvasElement getCanvasElement(){
+ return graphics.canvas;
+ }
+
+ public LoadingListener getLoadingListener () {
+ return loadingListener;
+ }
+
+ public void setLoadingListener (LoadingListener loadingListener) {
+ this.loadingListener = loadingListener;
+ }
+
@Override
- public void addLifecycleListener(LifecycleListener listener) {
- synchronized (lifecycleListeners) {
+ public void addLifecycleListener (LifecycleListener listener) {
+ synchronized(lifecycleListeners) {
lifecycleListeners.add(listener);
}
}
@Override
- public void removeLifecycleListener(LifecycleListener listener) {
- synchronized (lifecycleListeners) {
+ public void removeLifecycleListener (LifecycleListener listener) {
+ synchronized(lifecycleListeners) {
lifecycleListeners.removeValue(listener, true);
}
}
+
+ native static public void consoleLog(String message) /*-{
+ console.log( "GWT: " + message );
+ }-*/;
+
+ private native void addEventListeners () /*-{
+ var self = this;
+ $doc.addEventListener('visibilitychange', function (e) {
+ self.@com.badlogic.gdx.backends.gwt.GwtApplication::onVisibilityChange(Z)($doc['hidden'] !== true);
+ });
+ }-*/;
+
+ private void onVisibilityChange (boolean visible) {
+ if (visible) {
+ for (LifecycleListener listener : lifecycleListeners) {
+ listener.resume();
+ }
+ listener.resume();
+ } else {
+ for (LifecycleListener listener : lifecycleListeners) {
+ listener.pause();
+ }
+ listener.pause();
+ }
+ }
+
+ /**
+ * LoadingListener interface main purpose is to do some things before or after {@link GwtApplication#setupLoop()}
+ */
+ public interface LoadingListener{
+ /**
+ * Method called before the setup
+ */
+ public void beforeSetup();
+
+ /**
+ * Method called after the setup
+ */
+ public void afterSetup();
+ }
}
diff --git a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtGraphics.java b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtGraphics.java
index c62dd37c..429ffa29 100644
--- a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtGraphics.java
+++ b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtGraphics.java
@@ -1,12 +1,12 @@
/*******************************************************************************
- * Copyright 2011 See libgdx AUTHORS file.
- *
+ * Copyright 2011 See AUTHORS file.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,15 +16,20 @@
package com.badlogic.gdx.backends.gwt;
+import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
+import com.badlogic.gdx.graphics.Cursor;
+import com.badlogic.gdx.graphics.Cursor.SystemCursor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.GL30;
+import com.badlogic.gdx.graphics.Pixmap;
+import com.badlogic.gdx.graphics.glutils.GLVersion;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.dom.client.CanvasElement;
import com.google.gwt.dom.client.Document;
-import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.dom.client.Style;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.webgl.client.WebGLContextAttributes;
import com.google.gwt.webgl.client.WebGLRenderingContext;
@@ -36,20 +41,39 @@ import org.slf4j.LoggerFactory;
public class GwtGraphics implements Graphics {
static final Logger log = LoggerFactory.getLogger(GwtGraphics.class);
+ /* Enum values from http://www.w3.org/TR/screen-orientation. Filtered based on what the browsers actually support. */
+ public enum OrientationLockType {
+ LANDSCAPE("landscape"), PORTRAIT("portrait"), PORTRAIT_PRIMARY("portrait-primary"), PORTRAIT_SECONDARY(
+ "portrait-secondary"), LANDSCAPE_PRIMARY("landscape-primary"), LANDSCAPE_SECONDARY("landscape-secondary");
+
+ private final String name;
+
+ private OrientationLockType(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ ;
+
CanvasElement canvas;
WebGLRenderingContext context;
+ GLVersion glVersion;
GL20 gl;
String extensions;
float fps = 0;
long lastTimeStamp = System.currentTimeMillis();
+ long frameId = -1;
float deltaTime = 0;
float time = 0;
int frames;
GwtApplicationConfiguration config;
- boolean inFullscreenMode = false;
double pixelRatio;
- public GwtGraphics(Panel root, final GwtApplicationConfiguration config) {
+ public GwtGraphics(Panel root, GwtApplicationConfiguration config) {
this.pixelRatio = getDevicePixelRatioJSNI();
if (config.canvasId == null) {
@@ -64,10 +88,9 @@ public class GwtGraphics implements Graphics {
canvas.setWidth((int) (config.width * pixelRatio));
canvas.setHeight((int) (config.height * pixelRatio));
- canvas.getStyle().setWidth(config.width, Unit.PX);
- canvas.getStyle().setHeight(config.height, Unit.PX);
+ canvas.getStyle().setWidth(config.width, Style.Unit.PX);
+ canvas.getStyle().setHeight(config.height, Style.Unit.PX);
}
-
this.config = config;
WebGLContextAttributes attributes = WebGLContextAttributes.create();
@@ -75,11 +98,11 @@ public class GwtGraphics implements Graphics {
attributes.setStencil(config.stencil);
attributes.setAlpha(false);
attributes.setPremultipliedAlpha(false);
+ attributes.setPreserveDrawingBuffer(false);
context = WebGLRenderingContext.getContext(canvas, attributes);
if (context == null)
throw new GdxRuntimeException("Could not create Canvas for " + attributes);
-
context.viewport(0, 0, config.width, config.height);
// this actually *enables* the option to use std derivatives in shader..
@@ -92,6 +115,11 @@ public class GwtGraphics implements Graphics {
}
this.gl = config.useDebugGL ? new GwtGL20Debug(context) : new GdxGL(context);
+
+ String versionString = gl.glGetString(GL20.GL_VERSION);
+ String vendorString = gl.glGetString(GL20.GL_VENDOR);
+ String rendererString = gl.glGetString(GL20.GL_RENDERER);
+ glVersion = new GLVersion(Application.ApplicationType.WebGL, versionString, vendorString, rendererString);
}
public static native double getDevicePixelRatioJSNI() /*-{
@@ -125,6 +153,21 @@ public class GwtGraphics implements Graphics {
return canvas.getHeight();
}
+ @Override
+ public int getBackBufferWidth() {
+ return canvas.getWidth();
+ }
+
+ @Override
+ public int getBackBufferHeight() {
+ return canvas.getHeight();
+ }
+
+ @Override
+ public long getFrameId() {
+ return frameId;
+ }
+
@Override
public float getDeltaTime() {
return deltaTime;
@@ -140,6 +183,11 @@ public class GwtGraphics implements Graphics {
return GraphicsType.WebGL;
}
+ @Override
+ public GLVersion getGLVersion() {
+ return glVersion;
+ }
+
@Override
public float getPpiX() {
return 96;
@@ -162,13 +210,28 @@ public class GwtGraphics implements Graphics {
@Override
public boolean supportsDisplayModeChange() {
- return true;
+ return supportsFullscreenJSNI();
}
+ private native boolean supportsFullscreenJSNI() /*-{
+ if ("fullscreenEnabled" in $doc) {
+ return $doc.fullscreenEnabled;
+ }
+ if ("webkitFullscreenEnabled" in $doc) {
+ return $doc.webkitFullscreenEnabled;
+ }
+ if ("mozFullScreenEnabled" in $doc) {
+ return $doc.mozFullScreenEnabled;
+ }
+ if ("msFullscreenEnabled" in $doc) {
+ return $doc.msFullscreenEnabled;
+ }
+ return false;
+ }-*/;
+
@Override
public DisplayMode[] getDisplayModes() {
- return new DisplayMode[]{new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60,
- 8) {
+ return new DisplayMode[]{new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60, 8) {
}};
}
@@ -181,6 +244,21 @@ public class GwtGraphics implements Graphics {
}-*/;
private native boolean isFullscreenJSNI() /*-{
+ // Standards compliant check for fullscreen
+ if ("fullscreenElement" in $doc) {
+ return $doc.fullscreenElement != null;
+ }
+ // Vendor prefixed versions of standard check
+ if ("msFullscreenElement" in $doc) {
+ return $doc.msFullscreenElement != null;
+ }
+ if ("webkitFullscreenElement" in $doc) {
+ return $doc.webkitFullscreenElement != null;
+ }
+ if ("mozFullScreenElement" in $doc) { // Yes, with a capital 'S'
+ return $doc.mozFullScreenElement != null;
+ }
+ // Older, non-standard ways of checking for fullscreen
if ("webkitIsFullScreen" in $doc) {
return $doc.webkitIsFullScreen;
}
@@ -194,10 +272,28 @@ public class GwtGraphics implements Graphics {
if (!isFullscreen()) {
canvas.setWidth(config.width);
canvas.setHeight(config.height);
+ if (config.fullscreenOrientation != null) unlockOrientation();
+ } else {
+ /* We just managed to go full-screen. Check if the user has requested a specific orientation. */
+ if (config.fullscreenOrientation != null) lockOrientation(config.fullscreenOrientation);
}
}
private native boolean setFullscreenJSNI(GwtGraphics graphics, CanvasElement element) /*-{
+ // Attempt to use the non-prefixed standard API (https://fullscreen.spec.whatwg.org)
+ if (element.requestFullscreen) {
+ element.width = $wnd.screen.width;
+ element.height = $wnd.screen.height;
+ element.requestFullscreen();
+ $doc
+ .addEventListener(
+ "fullscreenchange",
+ function() {
+ graphics.@com.badlogic.gdx.backends.gwt.GwtGraphics::fullscreenChanged()();
+ }, false);
+ return true;
+ }
+ // Attempt to the vendor specific variants of the API
if (element.webkitRequestFullScreen) {
element.width = $wnd.screen.width;
element.height = $wnd.screen.height;
@@ -222,46 +318,140 @@ public class GwtGraphics implements Graphics {
}, false);
return true;
}
+ if (element.msRequestFullscreen) {
+ element.width = $wnd.screen.width;
+ element.height = $wnd.screen.height;
+ element.msRequestFullscreen();
+ $doc
+ .addEventListener(
+ "msfullscreenchange",
+ function() {
+ graphics.@com.badlogic.gdx.backends.gwt.GwtGraphics::fullscreenChanged()();
+ }, false);
+ return true;
+ }
+
return false;
}-*/;
private native void exitFullscreen() /*-{
+ if ($doc.exitFullscreen)
+ $doc.exitFullscreen();
+ if ($doc.msExitFullscreen)
+ $doc.msExitFullscreen();
if ($doc.webkitExitFullscreen)
$doc.webkitExitFullscreen();
if ($doc.mozExitFullscreen)
$doc.mozExitFullscreen();
+ if ($doc.webkitCancelFullScreen) // Old WebKit
+ $doc.webkitCancelFullScreen();
}-*/;
@Override
- public DisplayMode getDesktopDisplayMode() {
+ public DisplayMode getDisplayMode() {
return new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60, 8) {
};
}
@Override
- public boolean setDisplayMode(DisplayMode displayMode) {
- if (displayMode.width != getScreenWidthJSNI()
- && displayMode.height != getScreenHeightJSNI())
+ public boolean setFullscreenMode(DisplayMode displayMode) {
+ if (displayMode.width != getScreenWidthJSNI() && displayMode.height != getScreenHeightJSNI())
return false;
return setFullscreenJSNI(this, canvas);
}
@Override
- public boolean setDisplayMode(int width, int height, boolean fullscreen) {
- if (fullscreen) {
- if (width != getScreenWidthJSNI() && height != getScreenHeightJSNI())
- return false;
- return setFullscreenJSNI(this, canvas);
- } else {
- if (isFullscreenJSNI())
- exitFullscreen();
- canvas.setWidth(width);
- canvas.setHeight(height);
- canvas.getStyle().setWidth(width, Unit.PX);
- canvas.getStyle().setHeight(height, Unit.PX);
+ public boolean setWindowedMode(int width, int height) {
+ if (isFullscreenJSNI()) exitFullscreen();
+ canvas.setWidth(width);
+ canvas.setHeight(height);
+ return true;
+ }
+
+
+ @Override
+ public Monitor getPrimaryMonitor() {
+ return new GwtMonitor(0, 0, "Primary Monitor");
+ }
+
+ @Override
+ public Monitor getMonitor() {
+ return getPrimaryMonitor();
+ }
+
+ @Override
+ public Monitor[] getMonitors() {
+ return new Monitor[]{getPrimaryMonitor()};
+ }
+
+ @Override
+ public DisplayMode[] getDisplayModes(Monitor monitor) {
+ return getDisplayModes();
+ }
+
+ @Override
+ public DisplayMode getDisplayMode(Monitor monitor) {
+ return getDisplayMode();
+ }
+
+ /**
+ * Attempt to lock the orientation. Typically only supported when in full-screen mode.
+ *
+ * @param orientation the orientation to attempt locking
+ * @return did the locking succeed
+ */
+ public boolean lockOrientation(OrientationLockType orientation) {
+ return lockOrientationJSNI(orientation.getName());
+ }
+
+ /**
+ * Attempt to unlock the orientation.
+ *
+ * @return did the unlocking succeed
+ */
+ public boolean unlockOrientation() {
+ return unlockOrientationJSNI();
+ }
+
+ private native boolean lockOrientationJSNI(String orientationEnumValue) /*-{
+ var screen = $wnd.screen;
+
+ // Attempt to find the lockOrientation function
+ screen.gdxLockOrientation = screen.lockOrientation
+ || screen.mozLockOrientation || screen.msLockOrientation
+ || screen.webkitLockOrientation;
+
+ if (screen.gdxLockOrientation) {
+ return screen.gdxLockOrientation(orientationEnumValue);
+ }
+ // Actually, the Chrome guys do things a little different for now
+ else if (screen.orientation && screen.orientation.lock) {
+ screen.orientation.lock(orientationEnumValue);
+ // The Chrome API is async, so we can't at this point tell if we succeeded
return true;
}
- }
+ return false;
+ }-*/;
+
+ private native boolean unlockOrientationJSNI() /*-{
+ var screen = $wnd.screen;
+
+ // Attempt to find the lockOrientation function
+ screen.gdxUnlockOrientation = screen.unlockOrientation
+ || screen.mozUnlockOrientation || screen.msUnlockOrientation
+ || screen.webkitUnlockOrientation;
+
+ if (screen.gdxUnlockOrientation) {
+ return screen.gdxUnlockOrientation();
+ }
+ // Actually, the Chrome guys do things a little different for now
+ else if (screen.orientation && screen.orientation.unlock) {
+ screen.orientation.unlock();
+ // The Chrome API is async, so we can't at this point tell if we succeeded
+ return true;
+ }
+ return false;
+ }-*/;
@Override
public BufferFormat getBufferFormat() {
@@ -269,10 +459,12 @@ public class GwtGraphics implements Graphics {
}
@Override
- public boolean supportsExtension(String extension) {
- if (extensions == null)
- extensions = Gdx.gl.glGetString(GL20.GL_EXTENSIONS);
- return extensions.contains(extension);
+ public boolean supportsExtension(String extensionName) {
+ // Contrary to regular OpenGL, WebGL extensions need to be explicitly enabled before they can be used. See
+ // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Using_Extensions
+ // Thus, it is not safe to use an extension just because context.getSupportedExtensions() tells you it is available.
+ // We need to call getExtension() to enable it.
+ return context.getExtension(extensionName) != null;
}
public void update() {
@@ -292,6 +484,14 @@ public class GwtGraphics implements Graphics {
public void setTitle(String title) {
}
+ @Override
+ public void setUndecorated(boolean undecorated) {
+ }
+
+ @Override
+ public void setResizable(boolean resizable) {
+ }
+
@Override
public void setVSync(boolean vsync) {
}
@@ -335,8 +535,23 @@ public class GwtGraphics implements Graphics {
}
@Override
- public long getFrameId() {
- // TODO Auto-generated method stub
- return 0;
+ public Cursor newCursor(Pixmap pixmap, int xHotspot, int yHotspot) {
+ return new GwtCursor(pixmap, xHotspot, yHotspot);
+ }
+
+ @Override
+ public void setCursor(Cursor cursor) {
+ ((GwtApplication) Gdx.app).graphics.canvas.getStyle().setProperty("cursor", ((GwtCursor) cursor).cssCursorProperty);
+ }
+
+ @Override
+ public void setSystemCursor(SystemCursor systemCursor) {
+ ((GwtApplication) Gdx.app).graphics.canvas.getStyle().setProperty("cursor", GwtCursor.getNameForSystemCursor(systemCursor));
+ }
+
+ static class GwtMonitor extends Monitor {
+ protected GwtMonitor(int virtualX, int virtualY, String name) {
+ super(virtualX, virtualY, name);
+ }
}
}
diff --git a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtInput.java b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtInput.java
index a5e7d110..15015515 100644
--- a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtInput.java
+++ b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/backends/gwt/GwtInput.java
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,28 +21,30 @@ import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox;
import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox.TextInputDialogListener;
-import com.badlogic.gdx.graphics.Pixmap;
+import com.badlogic.gdx.utils.IntMap;
+import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.TimeUtils;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.CanvasElement;
-import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Touch;
import com.google.gwt.event.dom.client.KeyCodes;
-import java.util.HashSet;
-import java.util.Set;
-
public class GwtInput implements Input {
+ static final int MAX_TOUCHES = 20;
boolean justTouched = false;
- private boolean[] touched = new boolean[20];
- private int[] touchX = new int[20];
- private int[] touchY = new int[20];
- private int[] deltaX = new int[20];
- private int[] deltaY = new int[20];
- Set pressedButtons = new HashSet();
- Set pressedKeys = new HashSet();
+ private IntMap touchMap = new IntMap(20);
+ private boolean[] touched = new boolean[MAX_TOUCHES];
+ private int[] touchX = new int[MAX_TOUCHES];
+ private int[] touchY = new int[MAX_TOUCHES];
+ private int[] deltaX = new int[MAX_TOUCHES];
+ private int[] deltaY = new int[MAX_TOUCHES];
+ IntSet pressedButtons = new IntSet();
+ int pressedKeyCount = 0;
+ boolean[] pressedKeys = new boolean[256];
+ boolean keyJustPressed = false;
+ boolean[] justPressedKeys = new boolean[256];
InputProcessor processor;
char lastKeyCharPressed;
float keyRepeatTimer;
@@ -50,107 +52,154 @@ public class GwtInput implements Input {
final CanvasElement canvas;
boolean hasFocus = true;
- public GwtInput(CanvasElement canvas) {
+ public GwtInput (CanvasElement canvas) {
this.canvas = canvas;
hookEvents();
}
+ void reset () {
+ justTouched = false;
+ if (keyJustPressed) {
+ keyJustPressed = false;
+ for (int i = 0; i < justPressedKeys.length; i++) {
+ justPressedKeys[i] = false;
+ }
+ }
+ }
+
@Override
- public float getAccelerometerX() {
+ public float getAccelerometerX () {
return 0;
}
@Override
- public float getAccelerometerY() {
+ public float getAccelerometerY () {
return 0;
}
@Override
- public float getAccelerometerZ() {
+ public float getAccelerometerZ () {
return 0;
}
@Override
- public int getX() {
+ public float getGyroscopeX () {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public float getGyroscopeY () {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public float getGyroscopeZ () {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int getX () {
return touchX[0];
}
@Override
- public int getX(int pointer) {
+ public int getX (int pointer) {
return touchX[pointer];
}
@Override
- public int getDeltaX() {
+ public int getDeltaX () {
return deltaX[0];
}
@Override
- public int getDeltaX(int pointer) {
+ public int getDeltaX (int pointer) {
return deltaX[pointer];
}
@Override
- public int getY() {
+ public int getY () {
return touchY[0];
}
@Override
- public int getY(int pointer) {
+ public int getY (int pointer) {
return touchY[pointer];
}
@Override
- public int getDeltaY() {
+ public int getDeltaY () {
return deltaY[0];
}
@Override
- public int getDeltaY(int pointer) {
+ public int getDeltaY (int pointer) {
return deltaY[pointer];
}
@Override
- public boolean isTouched() {
- return touched[0];
+ public boolean isTouched () {
+ for (int pointer = 0; pointer < MAX_TOUCHES; pointer++) {
+ if (touched[pointer]) {
+ return true;
+ }
+ }
+ return false;
}
@Override
- public boolean justTouched() {
+ public boolean justTouched () {
return justTouched;
}
@Override
- public boolean isTouched(int pointer) {
+ public boolean isTouched (int pointer) {
return touched[pointer];
}
@Override
- public boolean isButtonPressed(int button) {
- return button == Buttons.LEFT && touched[0];
+ public boolean isButtonPressed (int button) {
+ return pressedButtons.contains(button) && touched[0];
}
@Override
- public boolean isKeyPressed(int key) {
- if (key == Keys.ANY_KEY)
- return pressedKeys.size() > 0;
- return pressedKeys.contains(key);
+ public boolean isKeyPressed (int key) {
+ if (key == Keys.ANY_KEY) {
+ return pressedKeyCount > 0;
+ }
+ if (key < 0 || key > 255) {
+ return false;
+ }
+ return pressedKeys[key];
}
@Override
- public void getTextInput(TextInputListener listener, String title, String text) {
- TextInputDialogBox dialog = new TextInputDialogBox(title, text, null);
+ public boolean isKeyJustPressed (int key) {
+ if (key == Keys.ANY_KEY) {
+ return keyJustPressed;
+ }
+ if (key < 0 || key > 255) {
+ return false;
+ }
+ return justPressedKeys[key];
+ }
+
+ public void getTextInput (TextInputListener listener, String title, String text, String hint) {
+ TextInputDialogBox dialog = new TextInputDialogBox(title, text, hint);
final TextInputListener capturedListener = listener;
dialog.setListener(new TextInputDialogListener() {
@Override
- public void onPositive(String text) {
+ public void onPositive (String text) {
if (capturedListener != null) {
capturedListener.input(text);
}
}
@Override
- public void onNegative() {
+ public void onNegative () {
if (capturedListener != null) {
capturedListener.canceled();
}
@@ -159,208 +208,174 @@ public class GwtInput implements Input {
}
@Override
- public void getPlaceholderTextInput(TextInputListener listener, String title, String placeholder) {
- TextInputDialogBox dialog = new TextInputDialogBox(title, null, placeholder);
- final TextInputListener capturedListener = listener;
- dialog.setListener(new TextInputDialogListener() {
- @Override
- public void onPositive(String text) {
- if (capturedListener != null) {
- capturedListener.input(text);
- }
- }
-
- @Override
- public void onNegative() {
- if (capturedListener != null) {
- capturedListener.canceled();
- }
- }
- });
+ public void setOnscreenKeyboardVisible (boolean visible) {
}
@Override
- public void setOnscreenKeyboardVisible(boolean visible) {
+ public void vibrate (int milliseconds) {
}
@Override
- public void vibrate(int milliseconds) {
+ public void vibrate (long[] pattern, int repeat) {
}
@Override
- public void vibrate(long[] pattern, int repeat) {
+ public void cancelVibrate () {
}
@Override
- public void cancelVibrate() {
- }
-
- @Override
- public float getAzimuth() {
+ public float getAzimuth () {
return 0;
}
@Override
- public float getPitch() {
+ public float getPitch () {
return 0;
}
@Override
- public float getRoll() {
+ public float getRoll () {
return 0;
}
@Override
- public void getRotationMatrix(float[] matrix) {
+ public void getRotationMatrix (float[] matrix) {
}
@Override
- public long getCurrentEventTime() {
+ public long getCurrentEventTime () {
return currentEventTimeStamp;
}
@Override
- public void setCatchBackKey(boolean catchBack) {
+ public void setCatchBackKey (boolean catchBack) {
}
@Override
- public void setCatchMenuKey(boolean catchMenu) {
+ public boolean isCatchBackKey () {
+ return false;
}
@Override
- public void setInputProcessor(InputProcessor processor) {
+ public void setCatchMenuKey (boolean catchMenu) {
+ }
+
+ @Override
+ public boolean isCatchMenuKey () {
+ return false;
+ }
+
+ @Override
+ public void setInputProcessor (InputProcessor processor) {
this.processor = processor;
}
@Override
- public InputProcessor getInputProcessor() {
+ public InputProcessor getInputProcessor () {
return processor;
}
@Override
- public boolean isPeripheralAvailable(Peripheral peripheral) {
- if (peripheral == Peripheral.Accelerometer)
- return false;
- if (peripheral == Peripheral.Compass)
- return false;
- if (peripheral == Peripheral.HardwareKeyboard)
- return true;
- if (peripheral == Peripheral.MultitouchScreen)
- return isTouchScreen();
- if (peripheral == Peripheral.OnscreenKeyboard)
- return false;
- if (peripheral == Peripheral.Vibrator)
- return false;
+ public boolean isPeripheralAvailable (Peripheral peripheral) {
+ if (peripheral == Peripheral.Accelerometer) return false;
+ if (peripheral == Peripheral.Compass) return false;
+ if (peripheral == Peripheral.HardwareKeyboard) return true;
+ if (peripheral == Peripheral.MultitouchScreen) return isTouchScreen();
+ if (peripheral == Peripheral.OnscreenKeyboard) return false;
+ if (peripheral == Peripheral.Vibrator) return false;
return false;
}
@Override
- public int getRotation() {
+ public int getRotation () {
return 0;
}
@Override
- public Orientation getNativeOrientation() {
+ public Orientation getNativeOrientation () {
return Orientation.Landscape;
}
- /**
- * from https://github.com/toji/game-shim/blob/master/game-shim.js
- *
- * @return is Cursor catched
- */
- private native boolean isCursorCatchedJSNI() /*-{
- if (!navigator.pointer) {
- navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
- }
- if (navigator.pointer) {
- if (typeof (navigator.pointer.isLocked) === "boolean") {
- // Chrome initially launched with this interface
- return navigator.pointer.isLocked;
- } else if (typeof (navigator.pointer.isLocked) === "function") {
- // Some older builds might provide isLocked as a function
- return navigator.pointer.isLocked();
- } else if (typeof (navigator.pointer.islocked) === "function") {
- // For compatibility with early Firefox build
- return navigator.pointer.islocked();
- }
- }
- return false;
- }-*/;
+ /** from https://github.com/toji/game-shim/blob/master/game-shim.js
+ * @return is Cursor catched */
+ private native boolean isCursorCatchedJSNI () /*-{
+ if (!navigator.pointer) {
+ navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
+ }
+ if (navigator.pointer) {
+ if (typeof (navigator.pointer.isLocked) === "boolean") {
+ // Chrome initially launched with this interface
+ return navigator.pointer.isLocked;
+ } else if (typeof (navigator.pointer.isLocked) === "function") {
+ // Some older builds might provide isLocked as a function
+ return navigator.pointer.isLocked();
+ } else if (typeof (navigator.pointer.islocked) === "function") {
+ // For compatibility with early Firefox build
+ return navigator.pointer.islocked();
+ }
+ }
+ return false;
+ }-*/;
- /**
- * from https://github.com/toji/game-shim/blob/master/game-shim.js
- *
- * @param element Canvas
- */
- private native void setCursorCatchedJSNI(CanvasElement element) /*-{
- // Navigator pointer is not the right interface according to spec.
- // Here for backwards compatibility only
- if (!navigator.pointer) {
- navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
- }
- // element.requestPointerLock
- if (!element.requestPointerLock) {
- element.requestPointerLock = (function() {
- return element.webkitRequestPointerLock
- || element.mozRequestPointerLock || function() {
- if (navigator.pointer) {
- navigator.pointer.lock(element);
- }
- };
- })();
- }
- element.requestPointerLock();
- }-*/;
+ /** from https://github.com/toji/game-shim/blob/master/game-shim.js
+ * @param element Canvas */
+ private native void setCursorCatchedJSNI (CanvasElement element) /*-{
+ // Navigator pointer is not the right interface according to spec.
+ // Here for backwards compatibility only
+ if (!navigator.pointer) {
+ navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
+ }
+ // element.requestPointerLock
+ if (!element.requestPointerLock) {
+ element.requestPointerLock = (function() {
+ return element.webkitRequestPointerLock
+ || element.mozRequestPointerLock || function() {
+ if (navigator.pointer) {
+ navigator.pointer.lock(element);
+ }
+ };
+ })();
+ }
+ element.requestPointerLock();
+ }-*/;
- /**
- * from https://github.com/toji/game-shim/blob/master/game-shim.js
- */
- private native void exitCursorCatchedJSNI() /*-{
- if (!$doc.exitPointerLock) {
- $doc.exitPointerLock = (function() {
- return $doc.webkitExitPointerLock || $doc.mozExitPointerLock
- || function() {
- if (navigator.pointer) {
- var elem = this;
- navigator.pointer.unlock();
- }
- };
- })();
- }
- }-*/;
+ /** from https://github.com/toji/game-shim/blob/master/game-shim.js */
+ private native void exitCursorCatchedJSNI () /*-{
+ if (!$doc.exitPointerLock) {
+ $doc.exitPointerLock = (function() {
+ return $doc.webkitExitPointerLock || $doc.mozExitPointerLock
+ || function() {
+ if (navigator.pointer) {
+ var elem = this;
+ navigator.pointer.unlock();
+ }
+ };
+ })();
+ }
+ }-*/;
- /**
- * from https://github.com/toji/game-shim/blob/master/game-shim.js
- *
+ /** from https://github.com/toji/game-shim/blob/master/game-shim.js
* @param event JavaScript Mouse Event
- * @return movement in x direction
- */
- private native float getMovementXJSNI(NativeEvent event) /*-{
- return event.movementX || event.webkitMovementX || 0;
- }-*/;
+ * @return movement in x direction */
+ private native float getMovementXJSNI (NativeEvent event) /*-{
+ return event.movementX || event.webkitMovementX || 0;
+ }-*/;
- /**
- * from https://github.com/toji/game-shim/blob/master/game-shim.js
- *
+ /** from https://github.com/toji/game-shim/blob/master/game-shim.js
* @param event JavaScript Mouse Event
- * @return movement in y direction
- */
- private native float getMovementYJSNI(NativeEvent event) /*-{
- return event.movementY || event.webkitMovementY || 0;
- }-*/;
+ * @return movement in y direction */
+ private native float getMovementYJSNI (NativeEvent event) /*-{
+ return event.movementY || event.webkitMovementY || 0;
+ }-*/;
- private static native boolean isTouchScreen() /*-{
- return (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
- }-*/;
+ private static native boolean isTouchScreen () /*-{
+ return (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
+ }-*/;
- /**
- * works only for Chrome > Version 18 with enabled Mouse Lock enable in
- * about:flags or start Chrome with the
- * --enable-pointer-lock flag
- */
+ /** works only for Chrome > Version 18 with enabled Mouse Lock enable in about:flags or start Chrome with the
+ * --enable-pointer-lock flag */
@Override
- public void setCursorCatched(boolean catched) {
+ public void setCursorCatched (boolean catched) {
if (catched)
setCursorCatchedJSNI(canvas);
else
@@ -368,89 +383,90 @@ public class GwtInput implements Input {
}
@Override
- public boolean isCursorCatched() {
+ public boolean isCursorCatched () {
return isCursorCatchedJSNI();
}
@Override
- public void setCursorPosition(int x, int y) {
+ public void setCursorPosition (int x, int y) {
// FIXME??
}
- @Override
- public void setCursorImage(Pixmap pixmap, int xHotspot, int yHotspot) {
- }
-
// kindly borrowed from our dear playn friends...
- static native void addEventListener(JavaScriptObject target, String name, GwtInput handler,
- boolean capture) /*-{
- target
- .addEventListener(
- name,
- function(e) {
- handler.@com.badlogic.gdx.backends.gwt.GwtInput::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e);
- }, capture);
- }-*/;
+ static native void addEventListener (JavaScriptObject target, String name, GwtInput handler, boolean capture) /*-{
+ target
+ .addEventListener(
+ name,
+ function(e) {
+ handler.@com.badlogic.gdx.backends.gwt.GwtInput::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e);
+ }, capture);
+ }-*/;
- private static native float getMouseWheelVelocity(NativeEvent evt) /*-{
- var delta = 0.0;
- var agentInfo = @com.badlogic.gdx.backends.gwt.GwtApplication::agentInfo()();
+ private static native float getMouseWheelVelocity (NativeEvent evt) /*-{
+ var delta = 0.0;
+ var agentInfo = @com.badlogic.gdx.backends.gwt.GwtApplication::agentInfo()();
- if (agentInfo.isFirefox) {
- if (agentInfo.isMacOS) {
- delta = 1.0 * evt.detail;
- } else {
- delta = 1.0 * evt.detail / 3;
- }
- } else if (agentInfo.isOpera) {
- if (agentInfo.isLinux) {
- delta = -1.0 * evt.wheelDelta / 80;
- } else {
- // on mac
- delta = -1.0 * evt.wheelDelta / 40;
- }
- } else if (agentInfo.isChrome || agentInfo.isSafari) {
- delta = -1.0 * evt.wheelDelta / 120;
- // handle touchpad for chrome
- if (Math.abs(delta) < 1) {
- if (agentInfo.isWindows) {
- delta = -1.0 * evt.wheelDelta;
- } else if (agentInfo.isMacOS) {
- delta = -1.0 * evt.wheelDelta / 3;
- }
- }
- }
- return delta;
- }-*/;
+ if (agentInfo.isFirefox) {
+ if (agentInfo.isMacOS) {
+ delta = 1.0 * evt.detail;
+ } else {
+ delta = 1.0 * evt.detail / 3;
+ }
+ } else if (agentInfo.isOpera) {
+ if (agentInfo.isLinux) {
+ delta = -1.0 * evt.wheelDelta / 80;
+ } else {
+ // on mac
+ delta = -1.0 * evt.wheelDelta / 40;
+ }
+ } else if (agentInfo.isChrome || agentInfo.isSafari) {
+ delta = -1.0 * evt.wheelDelta / 120;
+ // handle touchpad for chrome
+ if (Math.abs(delta) < 1) {
+ if (agentInfo.isWindows) {
+ delta = -1.0 * evt.wheelDelta;
+ } else if (agentInfo.isMacOS) {
+ delta = -1.0 * evt.wheelDelta / 3;
+ }
+ }
+ }
+ return delta;
+ }-*/;
- /**
- * Kindly borrowed from PlayN.
- **/
- protected static native String getMouseWheelEvent() /*-{
- if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
- return "DOMMouseScroll";
- } else {
- return "mousewheel";
- }
- }-*/;
+ /** Kindly borrowed from PlayN. **/
+ protected static native String getMouseWheelEvent () /*-{
+ if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
+ return "DOMMouseScroll";
+ } else {
+ return "mousewheel";
+ }
+ }-*/;
- /**
- * Kindly borrowed from PlayN.
- **/
- protected static float getRelativeX(NativeEvent e, Element target) {
- return e.getClientX() - target.getAbsoluteLeft() + target.getScrollLeft()
- + target.getOwnerDocument().getScrollLeft();
+ /** Kindly borrowed from PlayN. **/
+ protected int getRelativeX (NativeEvent e, CanvasElement target) {
+ float xScaleRatio = target.getWidth() * 1f / target.getClientWidth(); // Correct for canvas CSS scaling
+ return Math.round(xScaleRatio
+ * (e.getClientX() - target.getAbsoluteLeft() + target.getScrollLeft() + target.getOwnerDocument().getScrollLeft()));
}
- /**
- * Kindly borrowed from PlayN.
- **/
- protected static float getRelativeY(NativeEvent e, Element target) {
- return e.getClientY() - target.getAbsoluteTop() + target.getScrollTop()
- + target.getOwnerDocument().getScrollTop();
+ /** Kindly borrowed from PlayN. **/
+ protected int getRelativeY (NativeEvent e, CanvasElement target) {
+ float yScaleRatio = target.getHeight() * 1f / target.getClientHeight(); // Correct for canvas CSS scaling
+ return Math.round(yScaleRatio
+ * (e.getClientY() - target.getAbsoluteTop() + target.getScrollTop() + target.getOwnerDocument().getScrollTop()));
}
- private void hookEvents() {
+ protected int getRelativeX (Touch touch, CanvasElement target) {
+ float xScaleRatio = target.getWidth() * 1f / target.getClientWidth(); // Correct for canvas CSS scaling
+ return Math.round(xScaleRatio * touch.getRelativeX(target));
+ }
+
+ protected int getRelativeY (Touch touch, CanvasElement target) {
+ float yScaleRatio = target.getHeight() * 1f / target.getClientHeight(); // Correct for canvas CSS scaling
+ return Math.round(yScaleRatio * touch.getRelativeY(target));
+ }
+
+ private void hookEvents () {
addEventListener(canvas, "mousedown", this, true);
// addEventListener(Document.get(), "mousedown", this, true);
addEventListener(canvas, "mouseup", this, true);
@@ -464,6 +480,7 @@ public class GwtInput implements Input {
addEventListener(canvas, "keydown", this, false);
addEventListener(canvas, "keyup", this, false);
addEventListener(canvas, "keypress", this, false);
+
addEventListener(canvas, "touchstart", this, true);
addEventListener(canvas, "touchmove", this, true);
addEventListener(canvas, "touchcancel", this, true);
@@ -471,23 +488,19 @@ public class GwtInput implements Input {
}
- private int getButton(int button) {
- if (button == NativeEvent.BUTTON_LEFT)
- return Buttons.LEFT;
- if (button == NativeEvent.BUTTON_RIGHT)
- return Buttons.RIGHT;
- if (button == NativeEvent.BUTTON_MIDDLE)
- return Buttons.MIDDLE;
+ private int getButton (int button) {
+ if (button == NativeEvent.BUTTON_LEFT) return Buttons.LEFT;
+ if (button == NativeEvent.BUTTON_RIGHT) return Buttons.RIGHT;
+ if (button == NativeEvent.BUTTON_MIDDLE) return Buttons.MIDDLE;
return Buttons.LEFT;
}
- private void handleEvent(NativeEvent e) {
+ private void handleEvent (NativeEvent e) {
if (e.getType().equals("mousedown")) {
if (!e.getEventTarget().equals(canvas) || touched[0]) {
- float mouseX = (int) getRelativeX(e, canvas);
- float mouseY = (int) getRelativeY(e, canvas);
- if (mouseX < 0 || mouseX > Gdx.graphics.getWidth() || mouseY < 0
- || mouseY > Gdx.graphics.getHeight()) {
+ float mouseX = getRelativeX(e, canvas);
+ float mouseY = getRelativeY(e, canvas);
+ if (mouseX < 0 || mouseX > Gdx.graphics.getWidth() || mouseY < 0 || mouseY > Gdx.graphics.getHeight()) {
hasFocus = false;
}
return;
@@ -502,25 +515,24 @@ public class GwtInput implements Input {
this.touchX[0] += getMovementXJSNI(e);
this.touchY[0] += getMovementYJSNI(e);
} else {
- this.touchX[0] = (int) getRelativeX(e, canvas);
- this.touchY[0] = (int) getRelativeY(e, canvas);
+ this.touchX[0] = getRelativeX(e, canvas);
+ this.touchY[0] = getRelativeY(e, canvas);
}
this.currentEventTimeStamp = TimeUtils.nanoTime();
- if (processor != null)
- processor.touchDown(touchX[0], touchY[0], 0, getButton(e.getButton()));
+ if (processor != null) processor.touchDown(touchX[0], touchY[0], 0, getButton(e.getButton()));
}
if (e.getType().equals("mousemove")) {
if (isCursorCatched()) {
- this.deltaX[0] = (int) getMovementXJSNI(e);
- this.deltaY[0] = (int) getMovementYJSNI(e);
+ this.deltaX[0] = (int)getMovementXJSNI(e);
+ this.deltaY[0] = (int)getMovementYJSNI(e);
this.touchX[0] += getMovementXJSNI(e);
this.touchY[0] += getMovementYJSNI(e);
} else {
- this.deltaX[0] = (int) getRelativeX(e, canvas) - touchX[0];
- this.deltaY[0] = (int) getRelativeY(e, canvas) - touchY[0];
- this.touchX[0] = (int) getRelativeX(e, canvas);
- this.touchY[0] = (int) getRelativeY(e, canvas);
+ this.deltaX[0] = getRelativeX(e, canvas) - touchX[0];
+ this.deltaY[0] = getRelativeY(e, canvas) - touchY[0];
+ this.touchX[0] = getRelativeX(e, canvas);
+ this.touchY[0] = getRelativeY(e, canvas);
}
this.currentEventTimeStamp = TimeUtils.nanoTime();
if (processor != null) {
@@ -532,35 +544,33 @@ public class GwtInput implements Input {
}
if (e.getType().equals("mouseup")) {
- if (!touched[0])
- return;
+ if (!touched[0]) return;
this.pressedButtons.remove(getButton(e.getButton()));
- this.touched[0] = pressedButtons.size() > 0;
+ this.touched[0] = pressedButtons.size > 0;
if (isCursorCatched()) {
- this.deltaX[0] = (int) getMovementXJSNI(e);
- this.deltaY[0] = (int) getMovementYJSNI(e);
+ this.deltaX[0] = (int)getMovementXJSNI(e);
+ this.deltaY[0] = (int)getMovementYJSNI(e);
this.touchX[0] += getMovementXJSNI(e);
this.touchY[0] += getMovementYJSNI(e);
} else {
- this.deltaX[0] = (int) getRelativeX(e, canvas) - touchX[0];
- this.deltaY[0] = (int) getRelativeY(e, canvas) - touchY[0];
- this.touchX[0] = (int) getRelativeX(e, canvas);
- this.touchY[0] = (int) getRelativeY(e, canvas);
+ this.deltaX[0] = getRelativeX(e, canvas) - touchX[0];
+ this.deltaY[0] = getRelativeY(e, canvas) - touchY[0];
+ this.touchX[0] = getRelativeX(e, canvas);
+ this.touchY[0] = getRelativeY(e, canvas);
}
this.currentEventTimeStamp = TimeUtils.nanoTime();
this.touched[0] = false;
- if (processor != null)
- processor.touchUp(touchX[0], touchY[0], 0, getButton(e.getButton()));
+ if (processor != null) processor.touchUp(touchX[0], touchY[0], 0, getButton(e.getButton()));
}
if (e.getType().equals(getMouseWheelEvent())) {
if (processor != null) {
- processor.scrolled((int) getMouseWheelVelocity(e));
+ processor.scrolled((int)getMouseWheelVelocity(e));
}
this.currentEventTimeStamp = TimeUtils.nanoTime();
e.preventDefault();
}
if (e.getType().equals("keydown") && hasFocus) {
- //System.out.println("keydown");
+ // System.out.println("keydown");
int code = keyForCode(e.getKeyCode());
if (code == 67) {
e.preventDefault();
@@ -569,23 +579,31 @@ public class GwtInput implements Input {
processor.keyTyped('\b');
}
} else {
- if (this.pressedKeys.add(code) && processor != null) {
- processor.keyDown(code);
+ if (!pressedKeys[code]) {
+ pressedKeyCount++;
+ pressedKeys[code] = true;
+ keyJustPressed = true;
+ justPressedKeys[code] = true;
+ if (processor != null) {
+ processor.keyDown(code);
+ }
}
}
}
if (e.getType().equals("keypress") && hasFocus) {
- //System.out.println("keypress");
- char c = (char) e.getCharCode();
- if (processor != null)
- processor.keyTyped(c);
+ // System.out.println("keypress");
+ char c = (char)e.getCharCode();
+ if (processor != null) processor.keyTyped(c);
}
if (e.getType().equals("keyup") && hasFocus) {
- //System.out.println("keyup");
+ // System.out.println("keyup");
int code = keyForCode(e.getKeyCode());
- this.pressedKeys.remove(code);
+ if (pressedKeys[code]) {
+ pressedKeyCount--;
+ pressedKeys[code] = false;
+ }
if (processor != null) {
processor.keyUp(code);
}
@@ -596,10 +614,12 @@ public class GwtInput implements Input {
JsArray touches = e.getChangedTouches();
for (int i = 0, j = touches.length(); i < j; i++) {
Touch touch = touches.get(i);
- int touchId = touch.getIdentifier();
+ int real = touch.getIdentifier();
+ int touchId;
+ touchMap.put(real, touchId = getAvailablePointer());
touched[touchId] = true;
- touchX[touchId] = touch.getRelativeX(canvas);
- touchY[touchId] = touch.getRelativeY(canvas);
+ touchX[touchId] = getRelativeX(touch, canvas);
+ touchY[touchId] = getRelativeY(touch, canvas);
deltaX[touchId] = 0;
deltaY[touchId] = 0;
if (processor != null) {
@@ -613,11 +633,12 @@ public class GwtInput implements Input {
JsArray touches = e.getChangedTouches();
for (int i = 0, j = touches.length(); i < j; i++) {
Touch touch = touches.get(i);
- int touchId = touch.getIdentifier();
- deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
- deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
- touchX[touchId] = touch.getRelativeX(canvas);
- touchY[touchId] = touch.getRelativeY(canvas);
+ int real = touch.getIdentifier();
+ int touchId = touchMap.get(real);
+ deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId];
+ deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId];
+ touchX[touchId] = getRelativeX(touch, canvas);
+ touchY[touchId] = getRelativeY(touch, canvas);
if (processor != null) {
processor.touchDragged(touchX[touchId], touchY[touchId], touchId);
}
@@ -629,12 +650,14 @@ public class GwtInput implements Input {
JsArray touches = e.getChangedTouches();
for (int i = 0, j = touches.length(); i < j; i++) {
Touch touch = touches.get(i);
- int touchId = touch.getIdentifier();
+ int real = touch.getIdentifier();
+ int touchId = touchMap.get(real);
+ touchMap.remove(real);
touched[touchId] = false;
- deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
- deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
- touchX[touchId] = touch.getRelativeX(canvas);
- touchY[touchId] = touch.getRelativeY(canvas);
+ deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId];
+ deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId];
+ touchX[touchId] = getRelativeX(touch, canvas);
+ touchY[touchId] = getRelativeY(touch, canvas);
if (processor != null) {
processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT);
}
@@ -646,12 +669,14 @@ public class GwtInput implements Input {
JsArray touches = e.getChangedTouches();
for (int i = 0, j = touches.length(); i < j; i++) {
Touch touch = touches.get(i);
- int touchId = touch.getIdentifier();
+ int real = touch.getIdentifier();
+ int touchId = touchMap.get(real);
+ touchMap.remove(real);
touched[touchId] = false;
- deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
- deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
- touchX[touchId] = touch.getRelativeX(canvas);
- touchY[touchId] = touch.getRelativeY(canvas);
+ deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId];
+ deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId];
+ touchX[touchId] = getRelativeX(touch, canvas);
+ touchY[touchId] = getRelativeY(touch, canvas);
if (processor != null) {
processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT);
}
@@ -659,13 +684,18 @@ public class GwtInput implements Input {
this.currentEventTimeStamp = TimeUtils.nanoTime();
e.preventDefault();
}
- // if(hasFocus) e.preventDefault();
+// if(hasFocus) e.preventDefault();
}
- /**
- * borrowed from PlayN, thanks guys
- **/
- private static int keyForCode(int keyCode) {
+ private int getAvailablePointer () {
+ for (int i = 0; i < MAX_TOUCHES; i++) {
+ if (!touchMap.containsValue(i, false)) return i;
+ }
+ return -1;
+ }
+
+ /** borrowed from PlayN, thanks guys **/
+ private static int keyForCode (int keyCode) {
switch (keyCode) {
case KeyCodes.KEY_ALT:
return Keys.ALT_LEFT;
@@ -955,15 +985,4 @@ public class GwtInput implements Input {
private static final int KEY_CLOSE_BRACKET = 221;
private static final int KEY_SINGLE_QUOTE = 222;
- @Override
- public boolean isKeyJustPressed(int key) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean isCatchBackKey() {
- // TODO Auto-generated method stub
- return false;
- }
}
diff --git a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/graphics/Pixmap.java b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/graphics/Pixmap.java
index 6a6040fd..57893f49 100644
--- a/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/graphics/Pixmap.java
+++ b/vtm-web/src/org/oscim/gdx/emu/com/badlogic/gdx/graphics/Pixmap.java
@@ -1,12 +1,12 @@
/*******************************************************************************
- * Copyright 2011 See libgdx AUTHORS file.
- *
+ * Copyright 2011 See AUTHORS file.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,6 +16,11 @@
package com.badlogic.gdx.graphics;
+import java.nio.Buffer;
+import java.nio.IntBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
import com.badlogic.gdx.backends.gwt.GwtFileHandle;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.BufferUtils;
@@ -28,38 +33,48 @@ import com.google.gwt.canvas.dom.client.Context2d.Composite;
import com.google.gwt.dom.client.CanvasElement;
import com.google.gwt.dom.client.ImageElement;
-import java.nio.Buffer;
-import java.nio.IntBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
public class Pixmap implements Disposable {
public static Map pixmaps = new HashMap();
static int nextId = 0;
- /**
- * Different pixel formats.
+ /** Different pixel formats.
*
- * @author mzechner
- */
+ * @author mzechner */
public enum Format {
Alpha, Intensity, LuminanceAlpha, RGB565, RGBA4444, RGB888, RGBA8888;
+
+ public static int toGlFormat (Format format) {
+ if (format == Alpha) return GL20.GL_ALPHA;
+ if (format == Intensity) return GL20.GL_ALPHA;
+ if (format == LuminanceAlpha) return GL20.GL_LUMINANCE_ALPHA;
+ if (format == RGB565) return GL20.GL_RGB;
+ if (format == RGB888) return GL20.GL_RGB;
+ if (format == RGBA4444) return GL20.GL_RGBA;
+ if (format == RGBA8888) return GL20.GL_RGBA;
+ throw new GdxRuntimeException("unknown format: " + format);
+ }
+
+ public static int toGlType (Format format) {
+ if (format == Alpha) return GL20.GL_UNSIGNED_BYTE;
+ if (format == Intensity) return GL20.GL_UNSIGNED_BYTE;
+ if (format == LuminanceAlpha) return GL20.GL_UNSIGNED_BYTE;
+ if (format == RGB565) return GL20.GL_UNSIGNED_SHORT_5_6_5;
+ if (format == RGB888) return GL20.GL_UNSIGNED_BYTE;
+ if (format == RGBA4444) return GL20.GL_UNSIGNED_SHORT_4_4_4_4;
+ if (format == RGBA8888) return GL20.GL_UNSIGNED_BYTE;
+ throw new GdxRuntimeException("unknown format: " + format);
+ }
}
- /**
- * Blending functions to be set with {@link Pixmap#setBlending}.
- *
- * @author mzechner
- */
+ /** Blending functions to be set with {@link Pixmap#setBlending}.
+ * @author mzechner */
public enum Blending {
None, SourceOver
}
- /**
- * Filters to be used with {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
+ /** Filters to be used with {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
*
- * @author mzechner
- */
+ * @author mzechner */
public enum Filter {
NearestNeighbour, BiLinear
}
@@ -74,128 +89,139 @@ public class Pixmap implements Disposable {
int r = 255, g = 255, b = 255;
float a;
String color = make(r, g, b, a);
+ static String clearColor = make(255, 255, 255, 1.0f);
static Blending blending;
CanvasPixelArray pixels;
+ private ImageElement imageElement;
+
+ public Pixmap (FileHandle file) {
+ this(((GwtFileHandle)file).preloader.images.get(file.path()));
+ if (imageElement == null) throw new GdxRuntimeException("Couldn't load image '" + file.path() + "', file does not exist");
+ }
public Context2d getContext() {
+ ensureCanvasExists();
return context;
}
- public Pixmap(FileHandle file) {
- GwtFileHandle gwtFile = (GwtFileHandle) file;
- ImageElement img = gwtFile.preloader.images.get(file.path());
- if (img == null)
- throw new GdxRuntimeException("Couldn't load image '" + file.path() + "', file does not exist");
- create(img.getWidth(), img.getHeight(), Format.RGBA8888);
- context.setGlobalCompositeOperation(Composite.COPY);
- context.drawImage(img, 0, 0);
- context.setGlobalCompositeOperation(getComposite());
+ private static Composite getComposite () {
+ return Composite.SOURCE_OVER;
}
- private static Composite getComposite() {
- return blending == Blending.None ? Composite.COPY : Composite.SOURCE_OVER;
+ public Pixmap (ImageElement img) {
+ this(-1, -1, img);
}
- public Pixmap(ImageElement img) {
- create(img.getWidth(), img.getHeight(), Format.RGBA8888);
- context.drawImage(img, 0, 0);
+ public Pixmap (int width, int height, Format format) {
+ this(width, height, (ImageElement)null);
}
- public Pixmap(int width, int height, Format format) {
- create(width, height, format);
- }
+ private Pixmap(int width, int height, ImageElement imageElement) {
+ this.imageElement = imageElement;
+ this.width = imageElement != null ? imageElement.getWidth() : width;
+ this.height = imageElement != null ? imageElement.getHeight() : height;
- private void create(int width, int height, Format format2) {
- this.width = width;
- this.height = height;
- this.format = Format.RGBA8888;
- canvas = Canvas.createIfSupported();
- canvas.getCanvasElement().setWidth(width);
- canvas.getCanvasElement().setHeight(height);
- context = canvas.getContext2d();
- context.setGlobalCompositeOperation(getComposite());
buffer = BufferUtils.newIntBuffer(1);
id = nextId++;
buffer.put(0, id);
pixmaps.put(id, this);
}
- public static String make(int r2, int g2, int b2, float a2) {
+ private void create () {
+ canvas = Canvas.createIfSupported();
+ canvas.getCanvasElement().setWidth(width);
+ canvas.getCanvasElement().setHeight(height);
+ context = canvas.getContext2d();
+ context.setGlobalCompositeOperation(getComposite());
+ }
+
+ public static String make (int r2, int g2, int b2, float a2) {
return "rgba(" + r2 + "," + g2 + "," + b2 + "," + a2 + ")";
}
- /**
- * Sets the type of {@link Blending} to be used for all operations. Default is {@link Blending#SourceOver}.
- *
- * @param blending the blending type
- */
- public static void setBlending(Blending blending) {
+ /** Sets the type of {@link Blending} to be used for all operations. Default is {@link Blending#SourceOver}.
+ * @param blending the blending type */
+ public static void setBlending (Blending blending) {
Pixmap.blending = blending;
Composite composite = getComposite();
for (Pixmap pixmap : pixmaps.values()) {
+ pixmap.ensureCanvasExists();
pixmap.context.setGlobalCompositeOperation(composite);
}
}
- /**
- * @return the currently set {@link Blending}
- */
- public static Blending getBlending() {
+ /** @return the currently set {@link Blending} */
+ public static Blending getBlending () {
return blending;
}
- /**
- * Sets the type of interpolation {@link Filter} to be used in conjunction with
+ /** Sets the type of interpolation {@link Filter} to be used in conjunction with
* {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
- *
- * @param filter the filter.
- */
- public static void setFilter(Filter filter) {
+ * @param filter the filter. */
+ public static void setFilter (Filter filter) {
}
- public Format getFormat() {
+ public Format getFormat () {
return format;
}
- public int getGLInternalFormat() {
+ public int getGLInternalFormat () {
return GL20.GL_RGBA;
}
- public int getGLFormat() {
+ public int getGLFormat () {
return GL20.GL_RGBA;
}
- public int getGLType() {
+ public int getGLType () {
return GL20.GL_UNSIGNED_BYTE;
}
- public int getWidth() {
+ public int getWidth () {
return width;
}
- public int getHeight() {
+ public int getHeight () {
return height;
}
- public Buffer getPixels() {
+ public Buffer getPixels () {
return buffer;
}
@Override
- public void dispose() {
+ public void dispose () {
pixmaps.remove(id);
}
- public CanvasElement getCanvasElement() {
+ public CanvasElement getCanvasElement () {
+ ensureCanvasExists();
return canvas.getCanvasElement();
}
- /**
- * Sets the color for the following drawing operations
- *
- * @param color the color, encoded as RGBA8888
- */
- public void setColor(int color) {
+ private void ensureCanvasExists () {
+ if (canvas == null) {
+ create();
+ if (imageElement != null) {
+ context.setGlobalCompositeOperation(Composite.COPY);
+ context.drawImage(imageElement, 0, 0);
+ context.setGlobalCompositeOperation(getComposite());
+ }
+ }
+ }
+
+ public boolean canUseImageElement () {
+ return canvas == null && imageElement != null;
+ }
+
+ public ImageElement getImageElement () {
+ return imageElement;
+ }
+
+ /** Sets the color for the following drawing operations
+ * @param color the color, encoded as RGBA8888 */
+ public void setColor (int color) {
+ ensureCanvasExists();
r = (color >>> 24) & 0xff;
g = (color >>> 16) & 0xff;
b = (color >>> 8) & 0xff;
@@ -205,38 +231,34 @@ public class Pixmap implements Disposable {
context.setStrokeStyle(this.color);
}
- /**
- * Sets the color for the following drawing operations.
+ /** Sets the color for the following drawing operations.
*
* @param r The red component.
* @param g The green component.
* @param b The blue component.
- * @param a The alpha component.
- */
- public void setColor(float r, float g, float b, float a) {
- this.r = (int) (r * 255);
- this.g = (int) (g * 255);
- this.b = (int) (b * 255);
+ * @param a The alpha component. */
+ public void setColor (float r, float g, float b, float a) {
+ ensureCanvasExists();
+ this.r = (int)(r * 255);
+ this.g = (int)(g * 255);
+ this.b = (int)(b * 255);
this.a = a;
color = make(this.r, this.g, this.b, this.a);
context.setFillStyle(color);
context.setStrokeStyle(this.color);
}
- /**
- * Sets the color for the following drawing operations.
- *
- * @param color The color.
- */
- public void setColor(Color color) {
+ /** Sets the color for the following drawing operations.
+ * @param color The color. */
+ public void setColor (Color color) {
setColor(color.r, color.g, color.b, color.a);
}
- /**
- * Fills the complete bitmap with the currently set color.
- */
- public void fill() {
- context.fillRect(0, 0, getWidth(), getHeight());
+ /** Fills the complete bitmap with the currently set color. */
+ public void fill () {
+ ensureCanvasExists();
+ context.clearRect(0, 0, getWidth(), getHeight());
+ rectangle(0, 0, getWidth(), getHeight(), DrawType.FILL);
}
// /**
@@ -246,153 +268,117 @@ public class Pixmap implements Disposable {
// */
// public void setStrokeWidth (int width);
- /**
- * Draws a line between the given coordinates using the currently set color.
+ /** Draws a line between the given coordinates using the currently set color.
*
- * @param x The x-coodinate of the first point
- * @param y The y-coordinate of the first point
+ * @param x The x-coodinate of the first point
+ * @param y The y-coordinate of the first point
* @param x2 The x-coordinate of the first point
- * @param y2 The y-coordinate of the first point
- */
- public void drawLine(int x, int y, int x2, int y2) {
- context.beginPath();
- context.moveTo(x, y);
- context.lineTo(x2, y2);
- context.stroke();
- context.closePath();
+ * @param y2 The y-coordinate of the first point */
+ public void drawLine (int x, int y, int x2, int y2) {
+ line(x, y, x2, y2, DrawType.STROKE);
}
- /**
- * Draws a rectangle outline starting at x, y extending by width to the right and by height downwards (y-axis points downwards)
+ /** Draws a rectangle outline starting at x, y extending by width to the right and by height downwards (y-axis points downwards)
* using the current color.
*
- * @param x The x coordinate
- * @param y The y coordinate
- * @param width The width in pixels
- * @param height The height in pixels
- */
- public void drawRectangle(int x, int y, int width, int height) {
- context.beginPath();
- context.rect(x, y, width, height);
- context.stroke();
- context.closePath();
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param width The width in pixels
+ * @param height The height in pixels */
+ public void drawRectangle (int x, int y, int width, int height) {
+ rectangle(x, y, width, height, DrawType.STROKE);
}
- /**
- * Draws an area form another Pixmap to this Pixmap.
+ /** Draws an area form another Pixmap to this Pixmap.
*
* @param pixmap The other Pixmap
- * @param x The target x-coordinate (top left corner)
- * @param y The target y-coordinate (top left corner)
- */
- public void drawPixmap(Pixmap pixmap, int x, int y) {
- context.drawImage(pixmap.getCanvasElement(), x, y);
+ * @param x The target x-coordinate (top left corner)
+ * @param y The target y-coordinate (top left corner) */
+ public void drawPixmap (Pixmap pixmap, int x, int y) {
+ CanvasElement image = pixmap.getCanvasElement();
+ image(image, 0, 0, image.getWidth(), image.getHeight(), x, y, image.getWidth(), image.getHeight());
}
- /**
- * Draws an area form another Pixmap to this Pixmap.
+ /** Draws an area form another Pixmap to this Pixmap.
*
- * @param pixmap The other Pixmap
- * @param x The target x-coordinate (top left corner)
- * @param y The target y-coordinate (top left corner)
- * @param srcx The source x-coordinate (top left corner)
- * @param srcy The source y-coordinate (top left corner);
- * @param srcWidth The width of the area form the other Pixmap in pixels
- * @param srcHeight The height of the area form the other Pixmap in pixles
- */
- public void drawPixmap(Pixmap pixmap, int x, int y, int srcx, int srcy, int srcWidth, int srcHeight) {
- context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, x, y, srcWidth, srcHeight);
+ * @param pixmap The other Pixmap
+ * @param x The target x-coordinate (top left corner)
+ * @param y The target y-coordinate (top left corner)
+ * @param srcx The source x-coordinate (top left corner)
+ * @param srcy The source y-coordinate (top left corner);
+ * @param srcWidth The width of the area form the other Pixmap in pixels
+ * @param srcHeight The height of the area form the other Pixmap in pixles */
+ public void drawPixmap (Pixmap pixmap, int x, int y, int srcx, int srcy, int srcWidth, int srcHeight) {
+ CanvasElement image = pixmap.getCanvasElement();
+ image(image, srcx, srcy, srcWidth, srcHeight, x, y, srcWidth, srcHeight);
}
- /**
- * Draws an area form another Pixmap to this Pixmap. This will automatically scale and stretch the source image to the
+ /** Draws an area form another Pixmap to this Pixmap. This will automatically scale and stretch the source image to the
* specified target rectangle. Use {@link Pixmap#setFilter(Filter)} to specify the type of filtering to be used (nearest
* neighbour or bilinear).
*
- * @param pixmap The other Pixmap
- * @param srcx The source x-coordinate (top left corner)
- * @param srcy The source y-coordinate (top left corner);
- * @param srcWidth The width of the area form the other Pixmap in pixels
+ * @param pixmap The other Pixmap
+ * @param srcx The source x-coordinate (top left corner)
+ * @param srcy The source y-coordinate (top left corner);
+ * @param srcWidth The width of the area form the other Pixmap in pixels
* @param srcHeight The height of the area form the other Pixmap in pixles
- * @param dstx The target x-coordinate (top left corner)
- * @param dsty The target y-coordinate (top left corner)
- * @param dstWidth The target width
- * @param dstHeight the target height
- */
- public void drawPixmap(Pixmap pixmap, int srcx, int srcy, int srcWidth, int srcHeight, int dstx, int dsty, int dstWidth,
- int dstHeight) {
- context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, dstx, dsty, dstWidth, dstHeight);
+ * @param dstx The target x-coordinate (top left corner)
+ * @param dsty The target y-coordinate (top left corner)
+ * @param dstWidth The target width
+ * @param dstHeight the target height */
+ public void drawPixmap (Pixmap pixmap, int srcx, int srcy, int srcWidth, int srcHeight, int dstx, int dsty, int dstWidth,
+ int dstHeight) {
+ image(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, dstx, dsty, dstWidth, dstHeight);
}
- /**
- * Fills a rectangle starting at x, y extending by width to the right and by height downwards (y-axis points downwards) using
+ /** Fills a rectangle starting at x, y extending by width to the right and by height downwards (y-axis points downwards) using
* the current color.
*
- * @param x The x coordinate
- * @param y The y coordinate
- * @param width The width in pixels
- * @param height The height in pixels
- */
- public void fillRectangle(int x, int y, int width, int height) {
- context.fillRect(x, y, width, height);
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param width The width in pixels
+ * @param height The height in pixels */
+ public void fillRectangle (int x, int y, int width, int height) {
+ rectangle(x, y, width, height, DrawType.FILL);
}
- /**
- * Draws a circle outline with the center at x,y and a radius using the current color and stroke width.
+ /** Draws a circle outline with the center at x,y and a radius using the current color and stroke width.
*
- * @param x The x-coordinate of the center
- * @param y The y-coordinate of the center
- * @param radius The radius in pixels
- */
- public void drawCircle(int x, int y, int radius) {
- context.beginPath();
- context.arc(x, y, radius, 0, 2 * Math.PI, false);
- context.stroke();
- context.closePath();
+ * @param x The x-coordinate of the center
+ * @param y The y-coordinate of the center
+ * @param radius The radius in pixels */
+ public void drawCircle (int x, int y, int radius) {
+ circle(x, y, radius, DrawType.STROKE);
}
- /**
- * Fills a circle with the center at x,y and a radius using the current color.
+ /** Fills a circle with the center at x,y and a radius using the current color.
*
- * @param x The x-coordinate of the center
- * @param y The y-coordinate of the center
- * @param radius The radius in pixels
- */
- public void fillCircle(int x, int y, int radius) {
- context.beginPath();
- context.arc(x, y, radius, 0, 2 * Math.PI, false);
- context.fill();
- context.closePath();
+ * @param x The x-coordinate of the center
+ * @param y The y-coordinate of the center
+ * @param radius The radius in pixels */
+ public void fillCircle (int x, int y, int radius) {
+ circle(x, y, radius, DrawType.FILL);
}
- /**
- * Fills a triangle with vertices at x1,y1 and x2,y2 and x3,y3 using the current color.
+ /** Fills a triangle with vertices at x1,y1 and x2,y2 and x3,y3 using the current color.
*
* @param x1 The x-coordinate of vertex 1
* @param y1 The y-coordinate of vertex 1
* @param x2 The x-coordinate of vertex 2
* @param y2 The y-coordinate of vertex 2
* @param x3 The x-coordinate of vertex 3
- * @param y3 The y-coordinate of vertex 3
- */
- public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
- context.beginPath();
- context.moveTo(x1, y1);
- context.lineTo(x2, y2);
- context.lineTo(x3, y3);
- context.lineTo(x1, y1);
- context.fill();
- context.closePath();
+ * @param y3 The y-coordinate of vertex 3 */
+ public void fillTriangle (int x1, int y1, int x2, int y2, int x3, int y3) {
+ triangle(x1, y1, x2, y2, x3, y3, DrawType.FILL);
}
- /**
- * Returns the 32-bit RGBA8888 value of the pixel at x, y. For Alpha formats the RGB components will be one.
+ /** Returns the 32-bit RGBA8888 value of the pixel at x, y. For Alpha formats the RGB components will be one.
*
* @param x The x-coordinate
* @param y The y-coordinate
- * @return The pixel color in RGBA8888 format.
- */
- public int getPixel(int x, int y) {
+ * @return The pixel color in RGBA8888 format. */
+ public int getPixel (int x, int y) {
+ ensureCanvasExists();
if (pixels == null) pixels = context.getImageData(0, 0, width, height).getData();
int i = x * 4 + y * width * 4;
int r = pixels.get(i + 0) & 0xff;
@@ -402,26 +388,148 @@ public class Pixmap implements Disposable {
return (r << 24) | (g << 16) | (b << 8) | (a);
}
- /**
- * Draws a pixel at the given location with the current color.
+ /** Draws a pixel at the given location with the current color.
+ *
+ * @param x the x-coordinate
+ * @param y the y-coordinate */
+ public void drawPixel (int x, int y) {
+ rectangle(x, y, 1, 1, DrawType.FILL);
+ }
+
+ /** Draws a pixel at the given location with the given color.
*
* @param x the x-coordinate
* @param y the y-coordinate
- */
- public void drawPixel(int x, int y) {
- context.fillRect(x, y, 1, 1);
- }
-
- /**
- * Draws a pixel at the given location with the given color.
- *
- * @param x the x-coordinate
- * @param y the y-coordinate
- * @param color the color in RGBA8888 format.
- */
- public void drawPixel(int x, int y, int color) {
+ * @param color the color in RGBA8888 format. */
+ public void drawPixel (int x, int y, int color) {
setColor(color);
drawPixel(x, y);
}
+ private void circle (int x, int y, int radius, DrawType drawType) {
+ ensureCanvasExists();
+ if (blending == Blending.None) {
+ context.setFillStyle(clearColor);
+ context.setStrokeStyle(clearColor);
+ context.setGlobalCompositeOperation("destination-out");
+ context.beginPath();
+ context.arc(x, y, radius, 0, 2 * Math.PI, false);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ context.setFillStyle(color);
+ context.setStrokeStyle(color);
+ context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
+ }
+ context.beginPath();
+ context.arc(x, y, radius, 0, 2 * Math.PI, false);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ pixels = null;
+ }
+
+ private void line(int x, int y, int x2, int y2, DrawType drawType) {
+ ensureCanvasExists();
+ if (blending == Blending.None) {
+ context.setFillStyle(clearColor);
+ context.setStrokeStyle(clearColor);
+ context.setGlobalCompositeOperation("destination-out");
+ context.beginPath();
+ context.moveTo(x, y);
+ context.lineTo(x2, y2);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ context.setFillStyle(color);
+ context.setStrokeStyle(color);
+ context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
+ }
+ context.beginPath();
+ context.moveTo(x, y);
+ context.lineTo(x2, y2);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ pixels = null;
+ }
+
+ private void rectangle(int x, int y, int width, int height, DrawType drawType) {
+ ensureCanvasExists();
+ if (blending == Blending.None) {
+ context.setFillStyle(clearColor);
+ context.setStrokeStyle(clearColor);
+ context.setGlobalCompositeOperation("destination-out");
+ context.beginPath();
+ context.rect(x, y, width, height);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ context.setFillStyle(color);
+ context.setStrokeStyle(color);
+ context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
+ }
+ context.beginPath();
+ context.rect(x, y, width, height);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ pixels = null;
+ }
+
+ private void triangle(int x1, int y1, int x2, int y2, int x3, int y3, DrawType drawType) {
+ ensureCanvasExists();
+ if (blending == Blending.None) {
+ context.setFillStyle(clearColor);
+ context.setStrokeStyle(clearColor);
+ context.setGlobalCompositeOperation("destination-out");
+ context.beginPath();
+ context.moveTo(x1,y1);
+ context.lineTo(x2,y2);
+ context.lineTo(x3,y3);
+ context.lineTo(x1,y1);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ context.setFillStyle(color);
+ context.setStrokeStyle(color);
+ context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
+ }
+ context.beginPath();
+ context.moveTo(x1,y1);
+ context.lineTo(x2,y2);
+ context.lineTo(x3,y3);
+ context.lineTo(x1,y1);
+ fillOrStrokePath(drawType);
+ context.closePath();
+ pixels = null;
+ }
+
+ private void image (CanvasElement image, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight) {
+ ensureCanvasExists();
+ if (blending == Blending.None) {
+ context.setFillStyle(clearColor);
+ context.setStrokeStyle(clearColor);
+ context.setGlobalCompositeOperation("destination-out");
+ context.beginPath();
+ context.rect(dstX, dstY, dstWidth, dstHeight);
+ fillOrStrokePath(DrawType.FILL);
+ context.closePath();
+ context.setFillStyle(color);
+ context.setStrokeStyle(color);
+ context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
+ }
+ context.drawImage(image, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight);
+ pixels = null;
+ }
+
+ private void fillOrStrokePath(DrawType drawType) {
+ ensureCanvasExists();
+ switch (drawType) {
+ case FILL:
+ context.fill();
+ break;
+ case STROKE:
+ context.stroke();
+ break;
+ }
+ }
+
+ private enum DrawType {
+ FILL, STROKE
+ }
+
}
diff --git a/vtm-web/src/org/oscim/gdx/emu/java/io/FileInputStream.java b/vtm-web/src/org/oscim/gdx/emu/java/io/FileInputStream.java
new file mode 100644
index 00000000..e735a603
--- /dev/null
+++ b/vtm-web/src/org/oscim/gdx/emu/java/io/FileInputStream.java
@@ -0,0 +1,22 @@
+package java.io;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FileInputStream extends InputStream {
+
+ static final Logger log = LoggerFactory.getLogger(FileInputStream.class);
+
+ public FileInputStream(File f) {
+
+ }
+
+ public FileInputStream(String s) throws FileNotFoundException {
+ log.debug("FileInputStream {}", s);
+ }
+
+ @Override
+ public int read() throws IOException {
+ return 0;
+ }
+}
diff --git a/vtm-web/src/org/oscim/gdx/resources/js/soundmanager2-nodebug-jsmin.js b/vtm-web/src/org/oscim/gdx/resources/js/soundmanager2-nodebug-jsmin.js
new file mode 100755
index 00000000..d1614ed3
--- /dev/null
+++ b/vtm-web/src/org/oscim/gdx/resources/js/soundmanager2-nodebug-jsmin.js
@@ -0,0 +1,83 @@
+/** @license
+ *
+ * SoundManager 2: JavaScript Sound for the Web
+ * ----------------------------------------------
+ * http://schillmania.com/projects/soundmanager2/
+ *
+ * Copyright (c) 2007, Scott Schiller. All rights reserved.
+ * Code provided under the BSD License:
+ * http://schillmania.com/projects/soundmanager2/license.txt
+ *
+ * V2.97a.20150601
+ */
+(function(h,g){function w(gb,w){function Z(b){return c.preferFlash&&A&&!c.ignoreFlash&&c.flash[b]!==g&&c.flash[b]}function r(b){return function(c){var d=this._s;return d&&d._a?b.call(this,c):null}}this.setupOptions={url:gb||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1E3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0,
+forceUseGlobalHTML5Audio:!1,ignoreMobileRestrictions:!1,html5Test:/^(probably|maybe)$/i,preferFlash:!1,noSWFCache:!1,idPrefix:"sound"};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options={isMovieStar:null,usePeakData:!1,
+useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"],required:!1},opus:{type:["audio/ogg; codecs=opus",
+"audio/opus"],required:!1},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}};this.movieID="sm2-container";this.id=w||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20150601";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};
+this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1};this.sandbox={};this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=!1;var N,c=this,Oa=null,k=null,aa,u=navigator.userAgent,Pa=h.location.href.toString(),p=document,pa,Qa,qa,m,y=[],O=!1,P=!1,l=!1,B=!1,ra=!1,Q,x,sa,ba,ta,F,H,I,Ra,ua,va,ca,J,da,G,wa,R,xa,ea,K,Sa,ya,Ta,za,Ua,S=null,Aa=null,T,Ba,L,fa,ga,q,U=!1,Ca=!1,Va,Wa,Xa,ha=0,V=null,ia,W=[],X,v=null,Ya,ja,Y,D,ka,Da,Za,t,hb=Array.prototype.slice,
+z=!1,Ea,A,Fa,$a,C,la,ab=0,Ga,Ha=u.match(/(ipad|iphone|ipod)/i),Ia=u.match(/android/i),E=u.match(/msie/i),ib=u.match(/webkit/i),ma=u.match(/safari/i)&&!u.match(/chrome/i),Ja=u.match(/opera/i),na=u.match(/(mobile|pre\/|xoom)/i)||Ha||Ia,bb=!Pa.match(/usehtml5audio/i)&&!Pa.match(/sm2\-ignorebadua/i)&&ma&&!u.match(/silk/i)&&u.match(/OS X 10_6_([3-7])/i),Ka=p.hasFocus!==g?p.hasFocus():null,oa=ma&&(p.hasFocus===g||!p.hasFocus()),cb=!oa,db=/(mp3|mp4|mpa|m4a|m4b)/i,La=p.location?p.location.protocol.match(/http/i):
+null,jb=La?"":"http://",eb=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,fb="mpeg4 aac flv mov mp4 m4v f4v m4a m4b mp4v 3gp 3g2".split(" "),kb=new RegExp("\\.("+fb.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!La;var Ma;try{Ma=Audio!==g&&(Ja&&opera!==g&&10>opera.version()?new Audio(null):new Audio).canPlayType!==g}catch(lb){Ma=!1}this.hasHTML5=Ma;this.setup=function(b){var e=!c.url;b!==g&&l&&v&&c.ok();
+sa(b);if(!z)if(na){if(!c.setupOptions.ignoreMobileRestrictions||c.setupOptions.forceUseGlobalHTML5Audio)W.push(J.globalHTML5),z=!0}else c.setupOptions.forceUseGlobalHTML5Audio&&(W.push(J.globalHTML5),z=!0);if(!Ga&&na)if(c.setupOptions.ignoreMobileRestrictions)W.push(J.ignoreMobile);else if(c.setupOptions.useHTML5Audio=!0,c.setupOptions.preferFlash=!1,Ha)c.ignoreFlash=!0;else if(Ia&&!u.match(/android\s2\.3/i)||!Ia)z=!0;b&&(e&&R&&b.url!==g&&c.beginDelayedInit(),R||b.url===g||"complete"!==p.readyState||
+setTimeout(G,1));Ga=!0;return c};this.supported=this.ok=function(){return v?l&&!B:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(b){return aa(b)||p[b]||h[b]};this.createSound=function(b,e){function d(){a=fa(a);c.sounds[a.id]=new N(a);c.soundIDs.push(a.id);return c.sounds[a.id]}var a,f=null;if(!l||!c.ok())return!1;e!==g&&(b={id:b,url:e});a=x(b);a.url=ia(a.url);a.id===g&&(a.id=c.setupOptions.idPrefix+ab++);if(q(a.id,!0))return c.sounds[a.id];if(ja(a))f=d(),f._setup_html5(a);else{if(c.html5Only||
+c.html5.usingFlash&&a.url&&a.url.match(/data\:/i))return d();8a.instanceCount?(p(),f=a._setup_html5(),a.setPosition(a._iO.position),f.play()):(n=new Audio(a._iO.url),h=function(){t.remove(n,"ended",h);a._onfinish(a);ka(n);n=null},Na=function(){t.remove(n,"canplay",Na);try{n.currentTime=
+a._iO.position/1E3}catch(b){}n.play()},t.add(n,"ended",h),a._iO.volume!==g&&(n.volume=Math.max(0,Math.min(1,a._iO.volume/100))),a.muted&&(n.muted=!0),a._iO.position?t.add(n,"canplay",Na):n.play()):(f=k._start(a.id,a._iO.loops||1,9===m?a.position:a.position/1E3,a._iO.multiShot||!1),9!==m||f||a._iO.onplayerror&&a._iO.onplayerror.apply(a))}return a};this.stop=function(b){var c=a._iO;1===a.playState&&(a._onbufferchange(0),a._resetOnPosition(0),a.paused=!1,a.isHTML5||(a.playState=0),y(),c.to&&a.clearOnPosition(c.to),
+a.isHTML5?a._a&&(b=a.position,a.setPosition(0),a.position=b,a._a.pause(),a.playState=0,a._onTimer(),M()):(k._stop(a.id,b),c.serverURL&&a.unload()),a.instanceCount=0,a._iO={},c.onstop&&c.onstop.apply(a));return a};this.setAutoPlay=function(b){a._iO.autoPlay=b;a.isHTML5||(k._setAutoPlay(a.id,b),b&&(a.instanceCount||1!==a.readyState||a.instanceCount++))};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(b){b===g&&(b=0);var c=a.isHTML5?Math.max(b,0):Math.min(a.duration||a._iO.duration,
+Math.max(b,0));a.position=c;b=a.position/1E3;a._resetOnPosition(a.position);a._iO.position=c;if(!a.isHTML5)b=9===m?a.position:b,a.readyState&&2!==a.readyState&&k._setPosition(a.id,b,a.paused||!a.playState,a._iO.multiShot);else if(a._a){if(a._html5_canplay){if(a._a.currentTime!==b)try{a._a.currentTime=b,(0===a.playState||a.paused)&&a._a.pause()}catch(e){}}else if(b)return a;a.paused&&a._onTimer(!0)}return a};this.pause=function(b){if(a.paused||0===a.playState&&1!==a.readyState)return a;a.paused=!0;
+a.isHTML5?(a._setup_html5().pause(),M()):(b||b===g)&&k._pause(a.id,a._iO.multiShot);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){var b=a._iO;if(!a.paused)return a;a.paused=!1;a.playState=1;a.isHTML5?(a._setup_html5().play(),p()):(b.isMovieStar&&!b.serverURL&&a.setPosition(a.position),k._pause(a.id,b.multiShot));!u&&b.onplay?(b.onplay.apply(a),u=!0):b.onresume&&b.onresume.apply(a);return a};this.togglePause=function(){if(0===a.playState)return a.play({position:9!==m||a.isHTML5?
+a.position/1E3:a.position}),a;a.paused?a.resume():a.pause();return a};this.setPan=function(b,c){b===g&&(b=0);c===g&&(c=!1);a.isHTML5||k._setPan(a.id,b);a._iO.pan=b;c||(a.pan=b,a.options.pan=b);return a};this.setVolume=function(b,e){b===g&&(b=100);e===g&&(e=!1);a.isHTML5?a._a&&(c.muted&&!a.muted&&(a.muted=!0,a._a.muted=!0),a._a.volume=Math.max(0,Math.min(1,b/100))):k._setVolume(a.id,c.muted&&!a.muted||a.muted?0:b);a._iO.volume=b;e||(a.volume=b,a.options.volume=b);return a};this.mute=function(){a.muted=
+!0;a.isHTML5?a._a&&(a._a.muted=!0):k._setVolume(a.id,0);return a};this.unmute=function(){a.muted=!1;var b=a._iO.volume!==g;a.isHTML5?a._a&&(a._a.muted=!1):k._setVolume(a.id,b?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=this.onPosition=function(b,c,e){l.push({position:parseInt(b,10),method:c,scope:e!==g?e:a,fired:!1});return a};this.clearOnPosition=function(a,b){var c;a=parseInt(a,10);if(isNaN(a))return!1;for(c=0;c=b)return!1;for(--b;0<=b;b--)c=l[b],!c.fired&&a.position>=c.position&&(c.fired=!0,v++,c.method.apply(c.scope,[c.position]));return!0};this._resetOnPosition=function(a){var b,c;b=l.length;if(!b)return!1;for(--b;0<=b;b--)c=l[b],c.fired&&a<=c.position&&(c.fired=!1,v--);return!0};B=function(){var b=a._iO,c=b.from,e=b.to,d,f;f=function(){a.clearOnPosition(e,f);
+a.stop()};d=function(){if(null!==e&&!isNaN(e))a.onPosition(e,f)};null===c||isNaN(c)||(b.position=c,b.multiShot=!1,d());return b};r=function(){var b,c=a._iO.onposition;if(c)for(b in c)if(c.hasOwnProperty(b))a.onPosition(parseInt(b,10),c[b])};y=function(){var b,c=a._iO.onposition;if(c)for(b in c)c.hasOwnProperty(b)&&a.clearOnPosition(parseInt(b,10))};p=function(){a.isHTML5&&Va(a)};M=function(){a.isHTML5&&Wa(a)};f=function(b){b||(l=[],v=0);u=!1;a._hasTimer=null;a._a=null;a._html5_canplay=!1;a.bytesLoaded=
+null;a.bytesTotal=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.buffered=[];a.eqData=[];a.eqData.left=[];a.eqData.right=[];a.failures=0;a.isBuffering=!1;a.instanceOptions={};a.instanceCount=0;a.loaded=!1;a.metadata={};a.readyState=0;a.muted=!1;a.paused=!1;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.playState=0;a.position=null;a.id3={}};f();this._onTimer=function(b){var c,f=!1,g={};if(a._hasTimer||b)return a._a&&(b||(0opera.version()?new Audio(null):new Audio,c=a._a,c._called_load=!1,z&&(Oa=c);a.isHTML5=!0;a._a=c;c._s=a;n();a._apply_loop(c,b.loops);b.autoLoad||b.autoPlay?a.load():(c.autobuffer=!1,c.preload="auto");return c};n=function(){if(a._a._added_events)return!1;
+var b;a._a._added_events=!0;for(b in C)C.hasOwnProperty(b)&&a._a&&a._a.addEventListener(b,C[b],!1);return!0};h=function(){var b;a._a._added_events=!1;for(b in C)C.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,C[b],!1)};this._onload=function(b){var c=!!b||!a.isHTML5&&8===m&&a.duration;a.loaded=c;a.readyState=c?3:2;a._onbufferchange(0);a._iO.onload&&la(a,function(){a._iO.onload.apply(a,[c])});return!0};this._onbufferchange=function(b){if(0===a.playState||b&&a.isBuffering||!b&&!a.isBuffering)return!1;
+a.isBuffering=1===b;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a,[b]);return!0};this._onsuspend=function(){a._iO.onsuspend&&a._iO.onsuspend.apply(a);return!0};this._onfailure=function(b,c,e){a.failures++;if(a._iO.onfailure&&1===a.failures)a._iO.onfailure(b,c,e)};this._onwarning=function(b,c,e){if(a._iO.onwarning)a._iO.onwarning(b,c,e)};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);a._resetOnPosition(0);a.instanceCount&&(a.instanceCount--,a.instanceCount||(y(),a.playState=
+0,a.paused=!1,a.instanceCount=0,a.instanceOptions={},a._iO={},M(),a.isHTML5&&(a.position=0)),(!a.instanceCount||a._iO.multiShotEvents)&&b&&la(a,function(){b.apply(a)}))};this._whileloading=function(b,c,e,d){var f=a._iO;a.bytesLoaded=b;a.bytesTotal=c;a.duration=Math.floor(e);a.bufferLength=d;a.durationEstimate=a.isHTML5||f.isMovieStar?a.duration:f.duration?a.duration>f.duration?a.duration:f.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10);a.isHTML5||(a.buffered=[{start:0,end:a.duration}]);
+(3!==a.readyState||a.isHTML5)&&f.whileloading&&f.whileloading.apply(a)};this._whileplaying=function(b,c,e,d,f){var n=a._iO;if(isNaN(b)||null===b)return!1;a.position=Math.max(0,b);a._processOnPosition();!a.isHTML5&&8opera.version()?new Audio(null):new Audio:null,d,a,f={},n,h;n=c.audioFormats;for(d in n)if(n.hasOwnProperty(d)&&
+(a="audio/"+d,f[d]=b(n[d].type),f[a]=f[d],d.match(db)?(c.flash[d]=!0,c.flash[a]=!0):(c.flash[d]=!1,c.flash[a]=!1),n[d]&&n[d].related))for(h=n[d].related.length-1;0<=h;h--)f["audio/"+n[d].related[h]]=f[d],c.html5[n[d].related[h]]=f[d],c.flash[n[d].related[h]]=f[d];f.canPlayType=e?b:null;c.html5=x(c.html5,f);c.html5.usingFlash=Ya();v=c.html5.usingFlash;return!0};J={};T=function(){};fa=function(b){8===m&&1m&&(c.flashVersion=m=9);c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":9===m?" (AS3/Flash 9)":" (AS2/Flash 8)");8'}if(O&&P)return!1;if(c.html5Only)return va(),c.oMC=aa(c.movieID),qa(),P=O=!0,!1;var a=e||c.url,f=c.altURL||a,h=xa(),k=L(),m=null,m=p.getElementsByTagName("html")[0],l,r,q,m=m&&m.dir&&m.dir.match(/rtl/i);b=b===g?c.id:b;va();c.url=Ua(La?a:f);e=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;
+null!==c.wmode&&(u.match(/msie 8/i)||!E&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i)&&(W.push(J.spcWmode),c.wmode=null);h={name:b,id:b,src:e,quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:jb+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};c.debugFlash&&(h.FlashVars="debug=1");c.wmode||delete h.wmode;if(E)a=p.createElement("div"),r=
+['"].join("");else for(l in a=p.createElement("embed"),h)h.hasOwnProperty(l)&&
+a.setAttribute(l,h[l]);ya();k=L();if(h=xa())if(c.oMC=aa(c.movieID)||p.createElement("div"),c.oMC.id)q=c.oMC.className,c.oMC.className=(q?q+" ":"movieContainer")+(k?" "+k:""),c.oMC.appendChild(a),E&&(l=c.oMC.appendChild(p.createElement("div")),l.className="sm2-object-box",l.innerHTML=r),P=!0;else{c.oMC.id=c.movieID;c.oMC.className="movieContainer "+k;l=k=null;c.useFlashBlock||(c.useHighPerformance?k={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"}:(k={position:"absolute",
+width:"6px",height:"6px",top:"-9999px",left:"-9999px"},m&&(k.left=Math.abs(parseInt(k.left,10))+"px")));ib&&(c.oMC.style.zIndex=1E4);if(!c.debugFlash)for(q in k)k.hasOwnProperty(q)&&(c.oMC.style[q]=k[q]);try{E||c.oMC.appendChild(a),h.appendChild(c.oMC),E&&(l=c.oMC.appendChild(p.createElement("div")),l.className="sm2-object-box",l.innerHTML=r),P=!0}catch(t){throw Error(T("domError")+" \n"+t.toString());}}return O=!0};da=function(){if(c.html5Only)return ea(),!1;if(k||!c.url)return!1;k=c.getMovie(c.id);
+k||(S?(E?c.oMC.innerHTML=Aa:c.oMC.appendChild(S),S=null,O=!0):ea(c.id,c.url),k=c.getMovie(c.id));"function"===typeof c.oninitmovie&&setTimeout(c.oninitmovie,1);return!0};I=function(){setTimeout(Ra,1E3)};ua=function(){h.setTimeout(function(){c.setup({preferFlash:!1}).reboot();c.didFlashBlock=!0;c.beginDelayedInit()},1)};Ra=function(){var b,e=!1;if(!c.url||U)return!1;U=!0;t.remove(h,"load",I);if(A&&oa&&!Ka)return!1;l||(b=c.getMoviePercent(),0b&&(e=!0));setTimeout(function(){b=c.getMoviePercent();
+if(e)return U=!1,h.setTimeout(I,1),!1;!l&&cb&&(null===b?c.useFlashBlock||0===c.flashLoadTimeout?c.useFlashBlock&&Ba():!c.useFlashBlock&&X?ua():F({type:"ontimeout",ignoreInit:!0,error:{type:"INIT_FLASHBLOCK"}}):0!==c.flashLoadTimeout&&(!c.useFlashBlock&&X?ua():za(!0)))},c.flashLoadTimeout)};ca=function(){if(Ka||!oa)return t.remove(h,"focus",ca),!0;Ka=cb=!0;U=!1;I();t.remove(h,"focus",ca);return!0};Q=function(b){if(l)return!1;if(c.html5Only)return l=!0,H(),!0;var e=!0,d;c.useFlashBlock&&c.flashLoadTimeout&&
+!c.getMoviePercent()||(l=!0);d={type:!A&&v?"NO_FLASH":"INIT_TIMEOUT"};if(B||b)c.useFlashBlock&&c.oMC&&(c.oMC.className=L()+" "+(null===c.getMoviePercent()?"swf_timedout":"swf_error")),F({type:"ontimeout",error:d,ignoreInit:!0}),K(d),e=!1;B||(c.waitForWindowLoad&&!ra?t.add(h,"load",H):H());return e};Qa=function(){var b,e=c.setupOptions;for(b in e)e.hasOwnProperty(b)&&(c[b]===g?c[b]=e[b]:c[b]!==e[b]&&(c.setupOptions[b]=c[b]))};qa=function(){if(l)return!1;if(c.html5Only)return l||(t.remove(h,"load",
+c.beginDelayedInit),c.enabled=!0,Q()),!0;da();try{k._externalInterfaceTest(!1),Sa(!0,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||k._disableDebug(),c.enabled=!0,c.html5Only||t.add(h,"unload",pa)}catch(b){return K({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),za(!0),Q(),!1}Q();t.remove(h,"load",c.beginDelayedInit);return!0};G=function(){if(R)return!1;R=!0;Qa();ya();!A&&c.hasHTML5&&c.setup({useHTML5Audio:!0,preferFlash:!1});Za();!A&&v&&(W.push(J.needFlash),c.setup({flashLoadTimeout:1}));
+p.removeEventListener&&p.removeEventListener("DOMContentLoaded",G,!1);da();return!0};Da=function(){"complete"===p.readyState&&(G(),p.detachEvent("onreadystatechange",Da));return!0};wa=function(){ra=!0;G();t.remove(h,"load",wa)};Fa();t.add(h,"focus",ca);t.add(h,"load",I);t.add(h,"load",wa);p.addEventListener?p.addEventListener("DOMContentLoaded",G,!1):p.attachEvent?p.attachEvent("onreadystatechange",Da):K({type:"NO_DOM2_EVENTS",fatal:!0})}if(!h||!h.document)throw Error("SoundManager requires a browser with window and document objects.");
+var N=null;h.SM2_DEFER!==g&&SM2_DEFER||(N=new w);"object"===typeof module&&module&&"object"===typeof module.exports?(module.exports.SoundManager=w,module.exports.soundManager=N):"function"===typeof define&&define.amd&&define(function(){return{constructor:w,getInstance:function(g){!h.soundManager&&g instanceof Function&&(g=g(w),g instanceof w&&(h.soundManager=g));return h.soundManager}}});h.SoundManager=w;h.soundManager=N})(window);
\ No newline at end of file