-
Notifications
You must be signed in to change notification settings - Fork 32
/
System.hx
496 lines (396 loc) · 13.2 KB
/
System.hx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
package kha;
import kha.WindowOptions;
import kha.graphics4.TextureFormat;
import kha.input.Gamepad;
import kha.input.Keyboard;
import kha.input.Surface;
import kha.input.Mouse;
import kha.input.Pen;
import kha.input.Surface;
import kha.System;
import haxe.ds.Vector;
@:structInit
class SystemOptions {
@:optional public var title: String = "Kha";
@:optional public var width: Int = -1;
@:optional public var height: Int = -1;
@:optional public var window: WindowOptions = null;
@:optional public var framebuffer: FramebufferOptions = null;
/**
* Used to provide parameters for System.start
* @param title The application title is the default window title (unless the window parameter provides a title of its own)
* and is used for various other purposes - for example for save data locations
* @param width Just a shortcut which overwrites window.width if set
* @param height Just a shortcut which overwrites window.height if set
* @param window Optionally provide window options
* @param framebuffer Optionally provide framebuffer options
*/
public function new(title: String = "Kha", ?width: Int = -1, ?height: Int = -1, window: WindowOptions = null, framebuffer: FramebufferOptions = null) {
this.title = title;
this.window = window == null ? {} : window;
if (width > 0) {
this.window.width = width;
this.width = width;
}
else {
this.width = this.window.width;
}
if (height > 0) {
this.window.height = height;
this.height = height;
}
else {
this.height = this.window.height;
}
if (this.window.title == null) {
this.window.title = title;
}
this.framebuffer = framebuffer == null ? {} : framebuffer;
}
}
class System {
static var renderListeners: Array<Array<Framebuffer> -> Void> = [];
static var foregroundListeners: Array<Void -> Void> = [];
static var resumeListeners: Array<Void -> Void> = [];
static var pauseListeners: Array<Void -> Void> = [];
static var backgroundListeners: Array<Void -> Void> = [];
static var shutdownListeners: Array<Void -> Void> = [];
static var dropFilesListeners: Array<String -> Void> = [];
static var cutListener: Void->String = null;
static var copyListener: Void->String = null;
static var pasteListener: String->Void = null;
private static var startTime: Float;
private static var framebuffer: Framebuffer;
private static var keyboard: Keyboard;
private static var mouse: Mouse;
private static var surface: Surface;
private static var pen: Pen;
private static var maxGamepads: Int = 4;
private static var gamepads: Array<Gamepad>;
private static var mouseLockListeners: Array<Void->Void> = [];
public static function start(options: SystemOptions, callback: Window -> Void): Void {
Krom.init(options.title, options.width, options.height, options.framebuffer.samplesPerPixel, options.framebuffer.verticalSync, cast options.window.mode, options.window.windowFeatures, Krom.KROM_API, options.window.x, options.window.y, options.framebuffer.frequency);
startTime = Krom.getTime();
haxe.Log.trace = function(v: Dynamic, ?infos: haxe.PosInfos) {
var message = haxe.Log.formatOutput(v, infos);
Krom.log(message);
};
new Window(0);
Scheduler.init();
Shaders.init();
var g4 = new kha.graphics4.Graphics();
framebuffer = new Framebuffer(0, null, g4);
framebuffer.init(new kha.graphics2.Graphics(framebuffer), g4);
Krom.setCallback(renderCallback);
Krom.setDropFilesCallback(dropFilesCallback);
Krom.setCutCopyPasteCallback(cutCallback, copyCallback, pasteCallback);
Krom.setApplicationStateCallback(foregroundCallback, resumeCallback, pauseCallback, backgroundCallback, shutdownCallback);
keyboard = new Keyboard();
mouse = new Mouse();
surface = new Surface();
pen = new Pen();
gamepads = new Array<Gamepad>();
for (i in 0...maxGamepads) {
gamepads[i] = new Gamepad(i);
}
Krom.setKeyboardDownCallback(keyboardDownCallback);
Krom.setKeyboardUpCallback(keyboardUpCallback);
Krom.setKeyboardPressCallback(keyboardPressCallback);
Krom.setMouseDownCallback(mouseDownCallback);
Krom.setMouseUpCallback(mouseUpCallback);
Krom.setMouseMoveCallback(mouseMoveCallback);
Krom.setMouseWheelCallback(mouseWheelCallback);
Krom.setTouchDownCallback(touchDownCallback);
Krom.setTouchUpCallback(touchUpCallback);
Krom.setTouchMoveCallback(touchMoveCallback);
Krom.setPenDownCallback(penDownCallback);
Krom.setPenUpCallback(penUpCallback);
Krom.setPenMoveCallback(penMoveCallback);
Krom.setGamepadAxisCallback(gamepadAxisCallback);
Krom.setGamepadButtonCallback(gamepadButtonCallback);
Scheduler.start();
callback(Window.get(0));
}
/**
* The provided listener is called when new framebuffers are ready for rendering into.
* Each framebuffer corresponds to the kha.Window of the same index, single-window
* applications always receive an array of only one framebuffer.
* @param listener
* The callback to add
*/
public static function notifyOnFrames(listener: Array<Framebuffer> -> Void): Void {
renderListeners.push(listener);
}
/**
* Removes a previously set frames listener.
* @param listener
* The callback to remove
*/
public static function removeFramesListener(listener: Array<Framebuffer> -> Void): Void {
renderListeners.remove(listener);
}
public static function notifyOnApplicationState(foregroundListener: Void -> Void, resumeListener: Void -> Void, pauseListener: Void -> Void, backgroundListener: Void-> Void, shutdownListener: Void -> Void): Void {
if (foregroundListener != null) foregroundListeners.push(foregroundListener);
if (resumeListener != null) resumeListeners.push(resumeListener);
if (pauseListener != null) pauseListeners.push(pauseListener);
if (backgroundListener != null) backgroundListeners.push(backgroundListener);
if (shutdownListener != null) shutdownListeners.push(shutdownListener);
}
public static function notifyOnDropFiles(dropFilesListener: String -> Void): Void {
dropFilesListeners.push(dropFilesListener);
}
public static function removeDropListerer(listener: String -> Void): Void {
dropFilesListeners.remove(listener);
}
public static function notifyOnCutCopyPaste(cutListener: Void->String, copyListener: Void->String, pasteListener: String->Void): Void {
System.cutListener = cutListener;
System.copyListener = copyListener;
System.pasteListener = pasteListener;
}
static function render(framebuffers: Array<Framebuffer>): Void {
for (listener in renderListeners) {
listener(framebuffers);
}
}
private static function foreground(): Void {
for (listener in foregroundListeners) {
listener();
}
}
private static function resume(): Void {
for (listener in resumeListeners) {
listener();
}
}
private static function pause(): Void {
for (listener in pauseListeners) {
listener();
}
}
private static function background(): Void {
for (listener in backgroundListeners) {
listener();
}
}
private static function shutdown(): Void {
for (listener in shutdownListeners) {
listener();
}
}
private static function dropFiles(filePath: String): Void {
for (listener in dropFilesListeners) {
listener(filePath);
}
}
public static var time(get, null): Float;
private static function get_time(): Float {
return Krom.getTime() - startTime;
}
public static function windowWidth(window: Int = 0): Int {
return Window.get(window).width;
}
public static function windowHeight(window: Int = 0): Int {
return Window.all[window].height;
}
public static var systemId(get, null): String;
static function get_systemId(): String {
return Krom.systemId();
}
/**
* Pulses the vibration hardware on the device for time in milliseconds, if such hardware exists.
*/
public static function vibrate(ms:Int): Void {
}
/**
* The IS0 639 system current language identifier.
*/
public static var language(get, never): String;
private static function get_language(): String {
return Krom.language();
}
/**
* Schedules the application to stop as soon as possible. This is not possible on all targets.
* @return Returns true if the application can be stopped
*/
public static function stop(): Bool {
Krom.requestShutdown();
return true;
}
public static function loadUrl(url: String): Void {
Krom.loadUrl(url);
}
public static function safeZone(): Float {
return 1.0;
}
private static function renderCallback(): Void {
Scheduler.executeFrame();
System.render([framebuffer]);
}
private static function dropFilesCallback(filePath: String): Void {
System.dropFiles(filePath);
}
private static function copyCallback(): String {
if (System.copyListener != null) {
return System.copyListener();
}
else {
return null;
}
}
private static function cutCallback(): String {
if (System.cutListener != null) {
return System.cutListener();
}
else {
return null;
}
}
private static function pasteCallback(data: String): Void {
if (System.pasteListener != null) {
System.pasteListener(data);
}
}
private static function foregroundCallback(): Void {
System.foreground();
}
private static function resumeCallback(): Void {
System.resume();
}
private static function pauseCallback(): Void {
System.pause();
}
private static function backgroundCallback(): Void {
System.background();
}
private static function shutdownCallback(): Void {
System.shutdown();
}
private static function keyboardDownCallback(code: Int): Void {
keyboard.sendDownEvent(cast code);
}
private static function keyboardUpCallback(code: Int): Void {
keyboard.sendUpEvent(cast code);
}
private static function keyboardPressCallback(charCode: Int): Void {
keyboard.sendPressEvent(String.fromCharCode(charCode));
}
private static function mouseDownCallback(button: Int, x: Int, y: Int): Void {
mouse.sendDownEvent(0, button, x, y);
}
private static function mouseUpCallback(button: Int, x: Int, y: Int): Void {
mouse.sendUpEvent(0, button, x, y);
}
private static function mouseMoveCallback(x: Int, y: Int, mx: Int, my: Int): Void {
mouse.sendMoveEvent(0, x, y, mx, my);
}
private static function mouseWheelCallback(delta: Int): Void {
mouse.sendWheelEvent(0, delta);
}
private static function touchDownCallback(index: Int, x: Int, y: Int): Void {
surface.sendTouchStartEvent(index, x, y);
}
private static function touchUpCallback(index: Int, x: Int, y: Int): Void {
surface.sendTouchEndEvent(index, x, y);
}
private static function touchMoveCallback(index: Int, x: Int, y: Int): Void {
surface.sendMoveEvent(index, x, y);
}
private static function penDownCallback(x: Int, y: Int, pressure: Float): Void {
pen.sendDownEvent(0, x, y, pressure);
}
private static function penUpCallback(x: Int, y: Int, pressure: Float): Void {
pen.sendUpEvent(0, x, y, pressure);
}
private static function penMoveCallback(x: Int, y: Int, pressure: Float): Void {
pen.sendMoveEvent(0, x, y, pressure);
}
private static function gamepadAxisCallback(gamepad: Int, axis: Int, value: Float): Void {
gamepads[gamepad].sendAxisEvent(axis, value);
}
private static function gamepadButtonCallback(gamepad: Int, button: Int, value: Float): Void {
gamepads[gamepad].sendButtonEvent(button, value);
}
public static function getVsync(): Bool {
return true;
}
public static function getRefreshRate(): Int {
return 60;
}
public static function getMouse(num: Int): Mouse {
return mouse;
}
public static function getSurface(num: Int): Surface {
return surface;
}
public static function getPen(num: Int): Pen {
return pen;
}
public static function getKeyboard(num: Int): Keyboard {
return keyboard;
}
public static function showKeyboard() {
Krom.showKeyboard(true);
}
public static function hideKeyboard() {
Krom.showKeyboard(false);
}
public static function lockMouse(): Void {
if(!isMouseLocked()){
Krom.lockMouse();
for (listener in mouseLockListeners) {
listener();
}
}
}
public static function unlockMouse(): Void {
if(isMouseLocked()){
Krom.unlockMouse();
for (listener in mouseLockListeners) {
listener();
}
}
}
public static function canLockMouse(): Bool {
return Krom.canLockMouse();
}
public static function isMouseLocked(): Bool {
return Krom.isMouseLocked();
}
public static function notifyOfMouseLockChange(func: Void -> Void, error: Void -> Void): Void {
if (canLockMouse() && func != null) {
mouseLockListeners.push(func);
}
}
public static function removeFromMouseLockChange(func: Void -> Void, error: Void -> Void): Void {
if (canLockMouse() && func != null) {
mouseLockListeners.remove(func);
}
}
public static function hideSystemCursor(): Void {
Krom.showMouse(false);
}
public static function showSystemCursor(): Void {
Krom.showMouse(true);
}
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 static function changeResolution(width: Int, height: Int): Void {
}
public static function setKeepScreenOn(on: Bool): Void {
}
public static function getGamepadId(index: Int): String {
return "unkown";
}
}