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) {}
 | 
						|
}
 |