468 lines
13 KiB
Haxe
468 lines
13 KiB
Haxe
|
package kha;
|
||
|
|
||
|
import kha.System.SystemOptions;
|
||
|
import kha.input.Keyboard;
|
||
|
import kha.input.KeyCode;
|
||
|
import kha.input.Mouse;
|
||
|
import kha.java.Graphics;
|
||
|
import kha.System;
|
||
|
import kha.Window;
|
||
|
import java.javax.swing.JFrame;
|
||
|
import java.lang.Class;
|
||
|
import java.lang.System in Sys;
|
||
|
import java.lang.Object;
|
||
|
import java.lang.Throwable;
|
||
|
import java.NativeArray;
|
||
|
|
||
|
@:access(kha.System)
|
||
|
class JWindow extends JFrame implements java.awt.event.KeyListener implements java.awt.event.MouseListener implements java.awt.event.MouseMotionListener
|
||
|
implements java.awt.event.MouseWheelListener {
|
||
|
public var instance: JWindow;
|
||
|
|
||
|
var WIDTH: Int;
|
||
|
var HEIGHT: Int;
|
||
|
var syncrate = 60;
|
||
|
var canvas: java.awt.Canvas;
|
||
|
var vsynced = false;
|
||
|
var reset = false;
|
||
|
var framebuffer: kha.Framebuffer;
|
||
|
var painter: kha.java.Painter;
|
||
|
|
||
|
public static var mouseX: Int;
|
||
|
public static var mouseY: Int;
|
||
|
|
||
|
public function new() {
|
||
|
super();
|
||
|
instance = this;
|
||
|
painter = new kha.java.Painter();
|
||
|
framebuffer = new kha.Framebuffer(0, null, painter, null);
|
||
|
var g1 = new kha.graphics2.Graphics1(framebuffer);
|
||
|
framebuffer.init(g1, painter, null);
|
||
|
}
|
||
|
|
||
|
public function start(): Void {
|
||
|
createGame();
|
||
|
setupWindow();
|
||
|
createVSyncedDoubleBuffer();
|
||
|
mainLoop();
|
||
|
}
|
||
|
|
||
|
function setupWindow(): Void {
|
||
|
setIgnoreRepaint(true);
|
||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||
|
canvas = new java.awt.Canvas();
|
||
|
canvas.setIgnoreRepaint(true);
|
||
|
canvas.setSize(WIDTH, HEIGHT);
|
||
|
canvas.setFocusable(false);
|
||
|
add(canvas);
|
||
|
setResizable(false);
|
||
|
pack();
|
||
|
var screen: java.awt.Dimension = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||
|
var x = Std.int((screen.width - WIDTH) / 2);
|
||
|
var y = Std.int((screen.height - HEIGHT) / 2);
|
||
|
setLocation(x, y);
|
||
|
setTitle("Game");
|
||
|
setVisible(true);
|
||
|
addKeyListener(this);
|
||
|
canvas.addMouseListener(this);
|
||
|
canvas.addMouseMotionListener(this);
|
||
|
canvas.addMouseWheelListener(this);
|
||
|
}
|
||
|
|
||
|
function createVSyncedDoubleBuffer(): Void {
|
||
|
vsynced = true;
|
||
|
canvas.createBufferStrategy(2);
|
||
|
var bufferStrategy: java.awt.image.BufferStrategy = canvas.getBufferStrategy();
|
||
|
if (bufferStrategy != null) {
|
||
|
var caps: java.awt.BufferCapabilities = bufferStrategy.getCapabilities();
|
||
|
try {
|
||
|
// Class<?>
|
||
|
var ebcClass = Class.forName("sun.java2d.pipe.hw.ExtendedBufferCapabilities");
|
||
|
var vstClass = Class.forName("sun.java2d.pipe.hw.ExtendedBufferCapabilities$VSyncType");
|
||
|
// java.lang.reflect.Constructor<?>
|
||
|
// new Class[] { java.awt.BufferCapabilities.class, vstClass }
|
||
|
untyped var _class = untyped __java__("java.awt.BufferCapabilities.class");
|
||
|
var classes: NativeArray<Class<Dynamic>> = NativeArray.make(_class, vstClass);
|
||
|
var ebcConstructor = ebcClass.getConstructor(classes[0]);
|
||
|
var vSyncType: Object = vstClass.getField("VSYNC_ON").get(null);
|
||
|
// (java.awt.BufferCapabilities)
|
||
|
// new Object[]
|
||
|
var objs: NativeArray<Object> = NativeArray.make(cast(caps, Object), vSyncType);
|
||
|
var newCaps: java.awt.BufferCapabilities = ebcConstructor.newInstance(objs);
|
||
|
canvas.createBufferStrategy(2, newCaps);
|
||
|
// setCanChangeRefreshRate(false);
|
||
|
// setRefreshRate(60);
|
||
|
}
|
||
|
catch (t:Throwable) {
|
||
|
vsynced = false;
|
||
|
t.printStackTrace();
|
||
|
canvas.createBufferStrategy(2);
|
||
|
}
|
||
|
}
|
||
|
if (vsynced)
|
||
|
checkVSync();
|
||
|
}
|
||
|
|
||
|
function checkVSync(): Void {
|
||
|
var starttime = Sys.nanoTime();
|
||
|
for (i in 0...3) {
|
||
|
canvas.getBufferStrategy().show();
|
||
|
java.awt.Toolkit.getDefaultToolkit().sync();
|
||
|
}
|
||
|
var endtime = Sys.nanoTime();
|
||
|
if (endtime - starttime > 1000 * 1000 * 1000 / 60) {
|
||
|
vsynced = true;
|
||
|
Sys.out.println("VSync enabled.");
|
||
|
}
|
||
|
else
|
||
|
Sys.out.println("VSync not enabled, sorry.");
|
||
|
}
|
||
|
|
||
|
function mainLoop(): Void {
|
||
|
var lasttime = Sys.nanoTime();
|
||
|
while (true) {
|
||
|
if (vsynced)
|
||
|
update();
|
||
|
else {
|
||
|
var time = Sys.nanoTime();
|
||
|
while (time >= lasttime + 1000 * 1000 * 1000 / syncrate) {
|
||
|
lasttime += 1000 * 1000 * 1000 / syncrate;
|
||
|
update();
|
||
|
}
|
||
|
}
|
||
|
render();
|
||
|
if (reset)
|
||
|
resetGame();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function createGame(): Void {
|
||
|
WIDTH = System.windowWidth();
|
||
|
HEIGHT = System.windowHeight();
|
||
|
}
|
||
|
|
||
|
function resetGame(): Void {
|
||
|
reset = false;
|
||
|
createGame();
|
||
|
}
|
||
|
|
||
|
@:overload
|
||
|
function update(): Void {
|
||
|
Scheduler.executeFrame();
|
||
|
}
|
||
|
|
||
|
function render(): Void {
|
||
|
var bf: java.awt.image.BufferStrategy = canvas.getBufferStrategy();
|
||
|
var g: java.awt.Graphics2D = null;
|
||
|
try {
|
||
|
g = cast bf.getDrawGraphics();
|
||
|
painter.graphics = g;
|
||
|
painter.setRenderHint();
|
||
|
System.render([framebuffer]);
|
||
|
}
|
||
|
catch (e:Any) {
|
||
|
trace(e);
|
||
|
}
|
||
|
g.dispose();
|
||
|
bf.show();
|
||
|
java.awt.Toolkit.getDefaultToolkit().sync();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function keyPressed(e: java.awt.event.KeyEvent): Void {
|
||
|
// var keyCode: Int = e.getKeyCode();
|
||
|
// switch (keyCode) {
|
||
|
// case java.awt.event.KeyEvent.VK_RIGHT:
|
||
|
// pressKey(keyCode, KeyCode.RIGHT);
|
||
|
// case java.awt.event.KeyEvent.VK_LEFT:
|
||
|
// pressKey(keyCode, KeyCode.LEFT);
|
||
|
// case java.awt.event.KeyEvent.VK_UP:
|
||
|
// pressKey(keyCode, KeyCode.UP);
|
||
|
// case java.awt.event.KeyEvent.VK_DOWN:
|
||
|
// pressKey(keyCode, KeyCode.DOWN);
|
||
|
// case java.awt.event.KeyEvent.VK_SPACE:
|
||
|
// pressKey(keyCode, KeyCode.BUTTON_1);
|
||
|
// case java.awt.event.KeyEvent.VK_CONTROL:
|
||
|
// pressKey(keyCode, KeyCode.BUTTON_2);
|
||
|
// case java.awt.event.KeyEvent.VK_ENTER:
|
||
|
// //pressKey(keyCode, Key.ENTER);
|
||
|
// case java.awt.event.KeyEvent.VK_BACK_SPACE:
|
||
|
// //pressKey(keyCode, Key.BACKSPACE);
|
||
|
// default:
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function keyReleased(e: java.awt.event.KeyEvent): Void {
|
||
|
// var keyCode: Int = e.getKeyCode();
|
||
|
// switch (keyCode) {
|
||
|
// case java.awt.event.KeyEvent.VK_RIGHT:
|
||
|
// releaseKey(keyCode, KeyCode.RIGHT);
|
||
|
// case java.awt.event.KeyEvent.VK_LEFT:
|
||
|
// releaseKey(keyCode, KeyCode.LEFT);
|
||
|
// case java.awt.event.KeyEvent.VK_UP:
|
||
|
// releaseKey(keyCode, KeyCode.UP);
|
||
|
// case java.awt.event.KeyEvent.VK_DOWN:
|
||
|
// releaseKey(keyCode, KeyCode.DOWN);
|
||
|
// case java.awt.event.KeyEvent.VK_SPACE:
|
||
|
// releaseKey(keyCode, KeyCode.BUTTON_1);
|
||
|
// case java.awt.event.KeyEvent.VK_CONTROL:
|
||
|
// releaseKey(keyCode, KeyCode.BUTTON_2);
|
||
|
// case java.awt.event.KeyEvent.VK_ENTER:
|
||
|
// //releaseKey(keyCode, Key.ENTER);
|
||
|
// case java.awt.event.KeyEvent.VK_BACK_SPACE:
|
||
|
// //releaseKey(keyCode, Key.BACKSPACE);
|
||
|
// default:
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function keyTyped(e: java.awt.event.KeyEvent): Void {
|
||
|
// game.charKey(e.getKeyChar());
|
||
|
}
|
||
|
|
||
|
public function getSyncrate(): Int {
|
||
|
return syncrate;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function mouseClicked(arg0: java.awt.event.MouseEvent): Void {}
|
||
|
|
||
|
@Override
|
||
|
public function mouseEntered(arg0: java.awt.event.MouseEvent): Void {}
|
||
|
|
||
|
@Override
|
||
|
public function mouseExited(arg0: java.awt.event.MouseEvent): Void {}
|
||
|
|
||
|
@Override
|
||
|
public function mousePressed(arg0: java.awt.event.MouseEvent): Void {
|
||
|
mouseX = arg0.getX();
|
||
|
mouseY = arg0.getY();
|
||
|
|
||
|
// if (javax.swing.SwingUtilities.isLeftMouseButton(arg0))
|
||
|
// game.mouseDown(arg0.getX(), arg0.getY());
|
||
|
// else if (javax.swing.SwingUtilities.isRightMouseButton(arg0))
|
||
|
// game.rightMouseDown(arg0.getX(), arg0.getY());
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function mouseReleased(arg0: java.awt.event.MouseEvent): Void {
|
||
|
mouseX = arg0.getX();
|
||
|
mouseY = arg0.getY();
|
||
|
|
||
|
// if (javax.swing.SwingUtilities.isLeftMouseButton(arg0))
|
||
|
// game.mouseUp(arg0.getX(), arg0.getY());
|
||
|
// else if (javax.swing.SwingUtilities.isRightMouseButton(arg0))
|
||
|
// game.rightMouseUp(arg0.getX(), arg0.getY());
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function mouseDragged(arg0: java.awt.event.MouseEvent): Void {
|
||
|
mouseX = arg0.getX();
|
||
|
mouseY = arg0.getY();
|
||
|
// game.mouseMove(arg0.getPoint().x, arg0.getPoint().y);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function mouseMoved(arg0: java.awt.event.MouseEvent): Void {
|
||
|
mouseX = arg0.getX();
|
||
|
mouseY = arg0.getY();
|
||
|
// if (game != null) game.mouseMove(arg0.getPoint().x, arg0.getPoint().y);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public function mouseWheelMoved(arg0: java.awt.event.MouseWheelEvent): Void {
|
||
|
mouseX = arg0.getX();
|
||
|
mouseY = arg0.getY();
|
||
|
|
||
|
// game.mouseWheel(-arg0.getWheelRotation()); //invert
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@:allow(kha.SystemImpl.JWindow)
|
||
|
class SystemImpl {
|
||
|
public static var graphics(default, null): Graphics;
|
||
|
static var keyboard: Keyboard;
|
||
|
static var mouse: Mouse;
|
||
|
static var keyreleased: Array<Bool>;
|
||
|
|
||
|
public static function init(options: SystemOptions, callback: Window->Void) {
|
||
|
init2();
|
||
|
Scheduler.init();
|
||
|
if (options.width != -1)
|
||
|
myPixelWidth = options.width;
|
||
|
if (options.height != -1)
|
||
|
myPixelHeight = options.height;
|
||
|
|
||
|
var window = new Window(options.width, options.height);
|
||
|
Scheduler.start();
|
||
|
callback(window);
|
||
|
var jWindow = new JWindow();
|
||
|
jWindow.start();
|
||
|
}
|
||
|
|
||
|
public static function initEx(title: String, options: Array<WindowOptions>, windowCallback: Int->Void, callback: Window->Void) {
|
||
|
init({title: title, width: options[0].width, height: options[0].height}, callback);
|
||
|
}
|
||
|
|
||
|
static var startTime: Float;
|
||
|
|
||
|
public static function init2(): Void {
|
||
|
graphics = new Graphics();
|
||
|
startTime = getTimestamp();
|
||
|
mouse = new Mouse();
|
||
|
keyboard = new Keyboard();
|
||
|
keyreleased = [for (i in 0...256) true];
|
||
|
}
|
||
|
|
||
|
public static function getKeyboard(num: Int): Keyboard {
|
||
|
if (num == 0)
|
||
|
return keyboard;
|
||
|
else
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public static function getMouse(num: Int): Mouse {
|
||
|
if (num == 0)
|
||
|
return mouse;
|
||
|
else
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
function pressKey(keyCode: Int, button: KeyCode): Void {
|
||
|
if (keyreleased[keyCode]) { // avoid auto-repeat
|
||
|
keyreleased[keyCode] = false;
|
||
|
keyboard.sendDownEvent(button);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function releaseKey(keyCode: Int, button: KeyCode): Void {
|
||
|
keyreleased[keyCode] = true;
|
||
|
keyboard.sendUpEvent(button);
|
||
|
}
|
||
|
|
||
|
public static function getFrequency(): Int {
|
||
|
return 1000;
|
||
|
}
|
||
|
|
||
|
public static function getTimestamp(): Float {
|
||
|
return cast java.lang.System.currentTimeMillis();
|
||
|
}
|
||
|
|
||
|
public static function getTime(): Float {
|
||
|
return (getTimestamp() - startTime) / getFrequency();
|
||
|
}
|
||
|
|
||
|
public static function getScreenRotation(): ScreenRotation {
|
||
|
return ScreenRotation.RotationNone;
|
||
|
}
|
||
|
|
||
|
public static function getVsync(): Bool {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public static function getRefreshRate(): Int {
|
||
|
return 60;
|
||
|
}
|
||
|
|
||
|
public static function getSystemId(): String {
|
||
|
return "java";
|
||
|
}
|
||
|
|
||
|
public static function vibrate(ms: Int): Void {}
|
||
|
|
||
|
public static function getLanguage(): String {
|
||
|
final lang = java.util.Locale.getDefault().getLanguage();
|
||
|
return lang.substr(0, 2).toLowerCase();
|
||
|
}
|
||
|
|
||
|
static var myPixelWidth = 640;
|
||
|
static var myPixelHeight = 480;
|
||
|
|
||
|
public static function windowWidth(id: Int): Int {
|
||
|
return myPixelWidth;
|
||
|
}
|
||
|
|
||
|
public static function windowHeight(id: Int): Int {
|
||
|
return myPixelHeight;
|
||
|
}
|
||
|
|
||
|
public static function screenDpi(): Int {
|
||
|
return 96;
|
||
|
}
|
||
|
|
||
|
public static function changeResolution(width: Int, height: Int): Void {}
|
||
|
|
||
|
public static function requestShutdown(): Bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static function canSwitchFullscreen(): Bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static function isFullscreen(): Bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static function requestFullscreen(): Void {}
|
||
|
|
||
|
public static function exitFullscreen(): Void {}
|
||
|
|
||
|
public static function notifyOfFullscreenChange(func: Void->Void, error: Void->Void): Void {}
|
||
|
|
||
|
public static function removeFromFullscreenChange(func: Void->Void, error: Void->Void): Void {}
|
||
|
|
||
|
public function lockMouse(): Void {}
|
||
|
|
||
|
public function unlockMouse(): Void {}
|
||
|
|
||
|
public function canLockMouse(): Bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function isMouseLocked(): Bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {}
|
||
|
|
||
|
public function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {}
|
||
|
|
||
|
public static function setKeepScreenOn(on: Bool): Void {}
|
||
|
|
||
|
public static function loadUrl(url: String): Void {}
|
||
|
|
||
|
public static function safeZone(): Float {
|
||
|
return 1.0;
|
||
|
}
|
||
|
|
||
|
public static function waitingForLogin(): Bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static function disallowUserChange(): Void {}
|
||
|
|
||
|
public static function allowUserChange(): Void {}
|
||
|
|
||
|
public static function login(): Void {}
|
||
|
|
||
|
public static function automaticSafeZone(): Bool {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public static function setSafeZone(value: Float): Void {}
|
||
|
|
||
|
public static function unlockAchievement(id: Int): Void {}
|
||
|
|
||
|
public static function getGamepadId(index: Int): String {
|
||
|
return "unkown";
|
||
|
}
|
||
|
|
||
|
public static function getGamepadVendor(index: Int): String {
|
||
|
return "unknown";
|
||
|
}
|
||
|
|
||
|
public static function setGamepadRumble(index: Int, leftAmount: Float, rightAmount: Float) {}
|
||
|
}
|