This commit is contained in:
Dante
2026-05-21 23:40:20 -07:00
parent 3e2915dff7
commit 877a69d844
5737 changed files with 29796 additions and 1589684 deletions

View File

@ -134,22 +134,22 @@ enum abstract Color(Int) from Int from UInt to Int to UInt {
}
inline function set_Rb(i: Int): Int {
this = (Ab << 24) | (i << 16) | (Gb << 8) | Bb;
this = (this & 0xff00ffff) | (i << 16);
return i;
}
inline function set_Gb(i: Int): Int {
this = (Ab << 24) | (Rb << 16) | (i << 8) | Bb;
this = (this & 0xffff00ff) | (i << 8);
return i;
}
inline function set_Bb(i: Int): Int {
this = (Ab << 24) | (Rb << 16) | (Gb << 8) | i;
this = (this & 0xffffff00) | i;
return i;
}
inline function set_Ab(i: Int): Int {
this = (i << 24) | (Rb << 16) | (Gb << 8) | Bb;
this = (this & 0x00ffffff) | (i << 24);
return i;
}
@ -170,22 +170,22 @@ enum abstract Color(Int) from Int from UInt to Int to UInt {
}
inline function set_R(f: FastFloat): FastFloat {
this = (Std.int(A * 255) << 24) | (Std.int(f * 255) << 16) | (Std.int(G * 255) << 8) | Std.int(B * 255);
set_Rb(Std.int(f * 255));
return f;
}
inline function set_G(f: FastFloat): FastFloat {
this = (Std.int(A * 255) << 24) | (Std.int(R * 255) << 16) | (Std.int(f * 255) << 8) | Std.int(B * 255);
set_Gb(Std.int(f * 255));
return f;
}
inline function set_B(f: FastFloat): FastFloat {
this = (Std.int(A * 255) << 24) | (Std.int(R * 255) << 16) | (Std.int(G * 255) << 8) | Std.int(f * 255);
set_Bb(Std.int(f * 255));
return f;
}
inline function set_A(f: FastFloat): FastFloat {
this = (Std.int(f * 255) << 24) | (Std.int(R * 255) << 16) | (Std.int(G * 255) << 8) | Std.int(B * 255);
set_Ab(Std.int(f * 255));
return f;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,24 +2,33 @@ package kha;
import kha.WindowOptions;
@:structInit
private class AudioOptions {
/** Allow `audio2.Audio` api initialization on mobile browsers (only for HTML5 target) **/
public var allowMobileWebAudio = false;
}
@: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;
public var title: String = "Kha";
public var width: Int = -1;
public var height: Int = -1;
public var window: WindowOptions = null;
public var framebuffer: FramebufferOptions = null;
public var audio: AudioOptions = null;
/**
* Used to provide parameters for System.start
* 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 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
* @param audio Optionally provide audio options
*/
public function new(title: String = "Kha", ?width: Int = -1, ?height: Int = -1, window: WindowOptions = null, framebuffer: FramebufferOptions = null) {
public function new(title: String = "Kha", ?width: Int = -1, ?height: Int = -1, ?window: WindowOptions, ?framebuffer: FramebufferOptions,
?audio: AudioOptions) {
this.title = title;
this.window = window == null ? {} : window;
@ -44,6 +53,7 @@ class SystemOptions {
}
this.framebuffer = framebuffer == null ? {} : framebuffer;
this.audio = audio ?? {};
}
}
@ -77,7 +87,7 @@ class System {
@:deprecated("Use System.start instead")
public static function init(options: OldSystemOptions, callback: Void->Void): Void {
var features: kha.WindowFeatures = None;
var features: WindowFeatures = None;
if (options.resizable)
features |= WindowFeatures.FeatureResizable;
if (options.maximizable)

View File

@ -1,5 +1,7 @@
package kha.audio2;
import kha.internal.IntBox;
extern class Audio {
/**
* The samples per second natively used by the target system.
@ -10,8 +12,10 @@ extern class Audio {
* Requests additional audio data.
* Beware: This is called from a separate audio thread on some targets.
* See kha.audio2.Audio1 for sample code.
* This api is disabled on mobile for HTML5 target by default
* and can be enabled in `System.start` options.
*/
public static var audioCallback: Int->Buffer->Void;
public static var audioCallback: (outputBufferLength:IntBox, buffer:Buffer)->Void;
/**
* Similar to kha.audio1.Audio.stream, but only for hardware accelerated audio playback.

View File

@ -1,7 +0,0 @@
package kha.compute;
enum abstract Access(Int) to Int {
var Read = 0;
var Write = 1;
var ReadWrite = 2;
}

View File

@ -1,41 +0,0 @@
package kha.compute;
import kha.arrays.Float32Array;
import kha.Image;
import kha.FastFloat;
import kha.math.FastMatrix3;
import kha.math.FastMatrix4;
import kha.math.FastVector2;
import kha.math.FastVector3;
import kha.math.FastVector4;
import kha.graphics4.CubeMap;
import kha.graphics4.TextureAddressing;
import kha.graphics4.TextureFilter;
import kha.graphics4.MipMapFilter;
extern class Compute {
public static function setBool(location: ConstantLocation, value: Bool): Void;
public static function setInt(location: ConstantLocation, value: Int): Void;
public static function setFloat(location: ConstantLocation, value: FastFloat): Void;
public static function setFloat2(location: ConstantLocation, value1: FastFloat, value2: FastFloat): Void;
public static function setFloat3(location: ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat): Void;
public static function setFloat4(location: ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat, value4: FastFloat): Void;
public static function setFloats(location: ConstantLocation, values: Float32Array): Void;
public static function setVector2(location: ConstantLocation, value: FastVector2): Void;
public static function setVector3(location: ConstantLocation, value: FastVector3): Void;
public static function setVector4(location: ConstantLocation, value: FastVector4): Void;
public static function setMatrix(location: ConstantLocation, value: FastMatrix4): Void;
public static function setMatrix3(location: ConstantLocation, value: FastMatrix3): Void;
public static function setBuffer(buffer: ShaderStorageBuffer, index: Int): Void;
public static function setTexture(unit: TextureUnit, texture: Image, access: Access): Void;
public static function setSampledTexture(unit: TextureUnit, texture: Image): Void;
public static function setSampledDepthTexture(unit: TextureUnit, texture: Image): Void;
public static function setSampledCubeMap(unit: TextureUnit, cubeMap: CubeMap): Void;
public static function setSampledDepthCubeMap(unit: TextureUnit, cubeMap: CubeMap): Void;
public static function setTextureParameters(unit: TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void;
public static function setTexture3DParameters(unit: TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
wAddressing: TextureAddressing, minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void;
public static function setShader(shader: Shader): Void;
public static function compute(x: Int, y: Int, z: Int): Void;
}

View File

@ -1,3 +0,0 @@
package kha.compute;
extern class ConstantLocation {}

View File

@ -1,3 +0,0 @@
package kha.compute;
extern class TextureUnit {}

View File

@ -6,10 +6,12 @@ import kha.Blob;
import kha.Color;
import kha.FastFloat;
import kha.Image;
import kha.graphics4.ComputeShader;
import kha.graphics4.ConstantLocation;
import kha.graphics4.IndexBuffer;
import kha.graphics4.MipMapFilter;
import kha.graphics4.PipelineState;
import kha.graphics4.ShaderStorageBuffer;
import kha.graphics4.TextureFilter;
import kha.graphics4.TextureAddressing;
import kha.graphics4.TextureUnit;
@ -293,4 +295,16 @@ class Graphics4 implements kha.graphics4.Graphics {
public function maxBoundTextures(): Int {
return 16;
}
public function setShaderStorageBuffer(buffer: ShaderStorageBuffer, index: Int) {
}
public function setComputeShader(shader: ComputeShader) {
}
public function compute(x: Int, y: Int, z: Int) {
}
}

View File

@ -9,7 +9,7 @@ typedef Stbtt_uint16 = Int;
typedef Stbtt_int16 = Int;
typedef Stbtt_uint32 = Int;
typedef Stbtt_int32 = Int;
//typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
//typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
@ -48,9 +48,12 @@ class Stbtt_temp_region {
}
class Stbtt__buf {
public function new() { }
public var data: Blob;
public var cursor: Int;
public function new(data:Blob, cursor:Int) {
this.data = data;
this.cursor = cursor;
}
}
class Stbtt_bakedchar {
@ -60,7 +63,7 @@ class Stbtt_bakedchar {
public var y0: Int;
public var x1: Int;
public var y1: Int;
public var xoff: Float;
public var yoff: Float;
public var xadvance: Float;
@ -72,7 +75,7 @@ class Stbtt_aligned_quad {
public var y0: Float;
public var s0: Float;
public var t0: Float;
// bottom-right
public var x1: Float;
public var y1: Float;
@ -86,11 +89,11 @@ class Stbtt_packedchar {
public var y0: Int;
public var x1: Int;
public var y1: Int;
public var xoff: Float;
public var yoff: Float;
public var xadvance: Float;
public var xoff2: Float;
public var yoff2: Float;
}
@ -101,7 +104,7 @@ class Stbtt_pack_range {
public var array_of_unicode_codepoints: Vector<Int>; // if non-zero, then this is an array of unicode codepoints
public var num_chars: Int;
public var chardata_for_range: Stbtt_packedchar; // output
// don't set these, they're used internally
public var h_oversample: Int;
public var v_oversample: Int;
@ -214,7 +217,7 @@ class Stbtt__csctx {
class StbTruetype {
private static inline function STBTT_assert(value: Bool): Void { if (!value) throw "Error"; }
private static inline function STBTT_POINT_SIZE(x: Float): Float { return -x; }
public static inline var STBTT_vmove = 1;
public static inline var STBTT_vline = 2;
public static inline var STBTT_vcurve = 3;
@ -231,7 +234,7 @@ class StbTruetype {
public static inline var STBTT_PLATFORM_ID_MAC = 1;
public static inline var STBTT_PLATFORM_ID_ISO = 2;
public static inline var STBTT_PLATFORM_ID_MICROSOFT = 3;
// encodingID for STBTT_PLATFORM_ID_UNICODE
public static inline var STBTT_UNICODE_EID_UNICODE_1_0 = 0;
public static inline var STBTT_UNICODE_EID_UNICODE_1_1 = 1;
@ -244,7 +247,7 @@ class StbTruetype {
public static inline var STBTT_MS_EID_UNICODE_BMP = 1;
public static inline var STBTT_MS_EID_SHIFTJIS = 2;
public static inline var STBTT_MS_EID_UNICODE_FULL = 10;
// encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
public static inline var STBTT_MAC_EID_ROMAN = 0;
public static inline var STBTT_MAC_EID_ARABIC = 4;
@ -254,7 +257,7 @@ class StbTruetype {
public static inline var STBTT_MAC_EID_GREEK = 6;
public static inline var STBTT_MAC_EID_KOREAN = 3;
public static inline var STBTT_MAC_EID_RUSSIAN = 7;
// languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
// problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
public static inline var STBTT_MS_LANG_ENGLISH = 0x0409;
@ -269,7 +272,7 @@ class StbTruetype {
public static inline var STBTT_MS_LANG_SPANISH = 0x0409;
public static inline var STBTT_MS_LANG_HEBREW = 0x040d;
public static inline var STBTT_MS_LANG_SWEDISH = 0x041D;
// languageID for STBTT_PLATFORM_ID_MAC
public static inline var STBTT_MAC_LANG_ENGLISH = 0;
public static inline var STBTT_MAC_LANG_JAPANESE = 11;
@ -285,7 +288,7 @@ class StbTruetype {
public static inline var STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33;
public static inline var STBTT_MAC_LANG_ITALIAN = 3;
public static inline var STBTT_MAC_LANG_CHINESE_TRAD = 19;
public static inline var STBTT_MAX_OVERSAMPLE: Int = 8;
//**typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
public static inline var STBTT_RASTERIZER_VERSION: Int = 2;
@ -325,11 +328,8 @@ class StbTruetype {
}
private static inline function stbtt__new_buf(p: Blob, size: Int): Stbtt__buf {
var r: Stbtt__buf = new Stbtt__buf();
STBTT_assert(size < 0x40000000);
r.data = p;
r.cursor = 0;
return r;
return new Stbtt__buf(p, 0);
}
private static inline function stbtt__buf_get16(b: Stbtt__buf): Stbtt_uint32 {
@ -347,7 +347,7 @@ class StbTruetype {
return r;
}
private static inline function stbtt__cff_get_index(b: Stbtt__buf): Stbtt__buf {
private static function stbtt__cff_get_index(b: Stbtt__buf): Stbtt__buf {
var start = b.cursor;
var count = stbtt__buf_get16(b);
if (count > 0) {
@ -406,7 +406,7 @@ class StbTruetype {
return ret != null ? ret : stbtt__buf_range(b, 0, 0);
}
private static inline function stbtt__dict_get_ints(b: Stbtt__buf, key: Int, outcount: Int, out: Array<Stbtt_uint32>): Void {
private static function stbtt__dict_get_ints(b: Stbtt__buf, key: Int, outcount: Int, out: Array<Stbtt_uint32>): Void {
var i: Int = 0, operands = stbtt__dict_get(b, key);
while (i < outcount && operands.cursor < operands.data.length) {
out[i] = stbtt__cff_int(operands);
@ -420,7 +420,7 @@ class StbTruetype {
return stbtt__buf_get16(b);
}
private static inline function stbtt__cff_index_get(b: Stbtt__buf, i: Int): Stbtt__buf {
private static function stbtt__cff_index_get(b: Stbtt__buf, i: Int): Stbtt__buf {
stbtt__buf_seek(b, 0);
var count: Int = stbtt__buf_get16(b);
var offsize: Int = stbtt__buf_get8(b);
@ -432,24 +432,24 @@ class StbTruetype {
return stbtt__buf_range(b, 2+(count+1)*offsize+start, end - start);
}
private static inline function ttBYTE(p: Blob, pos: Int = 0): Stbtt_uint8 {
private static function ttBYTE(p: Blob, pos: Int = 0): Stbtt_uint8 {
return p.readU8(pos);
}
private static inline function ttCHAR(p: Blob, pos: Int = 0): Stbtt_int8 {
private static function ttCHAR(p: Blob, pos: Int = 0): Stbtt_int8 {
var n = p.readU8(pos);
if (n >= 128)
return n - 256;
return n;
}
private static inline function ttUSHORT(p: Blob, pos: Int = 0): Stbtt_uint16 {
private static function ttUSHORT(p: Blob, pos: Int = 0): Stbtt_uint16 {
var ch1 = p.readU8(pos + 0);
var ch2 = p.readU8(pos + 1);
return ch2 | (ch1 << 8);
}
private static inline function ttSHORT(p: Blob, pos: Int = 0): Stbtt_int16 {
private static function ttSHORT(p: Blob, pos: Int = 0): Stbtt_int16 {
var ch1 = p.readU8(pos + 0);
var ch2 = p.readU8(pos + 1);
var n = ch2 | (ch1 << 8);
@ -457,10 +457,10 @@ class StbTruetype {
return n - 0x10000;
return n;
}
private static inline function ttULONG(p: Blob, pos: Int = 0): Stbtt_uint32 { return ttLONG(p, pos); }
private static inline function ttLONG(p: Blob, pos: Int = 0): Stbtt_int32 {
private static function ttULONG(p: Blob, pos: Int = 0): Stbtt_uint32 { return ttLONG(p, pos); }
private static function ttLONG(p: Blob, pos: Int = 0): Stbtt_int32 {
var ch1 = p.readU8(pos + 0);
var ch2 = p.readU8(pos + 1);
var ch3 = p.readU8(pos + 2);
@ -471,9 +471,9 @@ class StbTruetype {
private static inline function to_stbtt_uint16(value: Int) {
return value & 0xffff;
}
private static inline function ttFixed(p: Blob, pos: Int = 0): Stbtt_int32 { return ttLONG(p, pos); }
private static inline function stbtt_tag4(p: Blob, pos: Int, c0: Int, c1: Int, c2: Int, c3: Int): Bool { return p.readU8(pos + 0) == c0 && p.readU8(pos + 1) == c1 && p.readU8(pos + 2) == c2 && p.readU8(pos + 3) == c3; }
private static inline function stbtt_tag(p: Blob, pos: Int, str: String): Bool { return stbtt_tag4(p, pos, str.charCodeAt(0), str.charCodeAt(1), str.charCodeAt(2), str.charCodeAt(3)); }
@ -626,7 +626,7 @@ class StbTruetype {
// the same regardless of glyph.
numTables = ttUSHORT(data, cmap + 2);
info.index_map = 0;
for (i in 0...numTables) {
var encoding_record: Stbtt_uint32 = cmap + 4 + 8 * i;
// find an encoding we understand:
@ -816,7 +816,7 @@ class StbTruetype {
}
return num_vertices;
}
private static function copyVertices(from: Vector<Stbtt_vertex>, to: Vector<Stbtt_vertex>, offset: Int, count: Int): Void {
for (i in 0...count) {
to[offset + i] = from[i];
@ -938,7 +938,7 @@ class StbTruetype {
if (i != 0)
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
// now start the new one
// now start the new one
start_off = (flags & 1 == 0);
if (start_off) {
// if we start off with an off-curve point, then when we need to find a point on the curve
@ -1029,7 +1029,7 @@ class StbTruetype {
mtx2 = ttSHORT(data, compIndex)/16384.0; compIndex+=2;
mtx3 = ttSHORT(data, compIndex)/16384.0; compIndex+=2;
}
// Find transformation scales.
m = Math.sqrt(mtx0*mtx0 + mtx1*mtx1);
n = Math.sqrt(mtx2*mtx2 + mtx3*mtx3);
@ -1078,7 +1078,7 @@ class StbTruetype {
}
}
private static inline function STBTT__CSCTX_INIT(bounds: Bool): Stbtt__csctx {
private static function STBTT__CSCTX_INIT(bounds: Bool): Stbtt__csctx {
var tmp = new Stbtt__csctx();
tmp.bounds = bounds;
tmp.started = false;
@ -1104,7 +1104,7 @@ class StbTruetype {
c.started = true;
}
private static inline function stbtt__csctx_v(c: Stbtt__csctx, type: Stbtt_uint8, x: Stbtt_int32, y: Stbtt_int32, cx: Stbtt_int32, cy: Stbtt_int32, cx1: Stbtt_int32, cy1: Stbtt_int32): Void {
private static function stbtt__csctx_v(c: Stbtt__csctx, type: Stbtt_uint8, x: Stbtt_int32, y: Stbtt_int32, cx: Stbtt_int32, cy: Stbtt_int32, cx1: Stbtt_int32, cy1: Stbtt_int32): Void {
if (c.bounds) {
stbtt__track_vertex(c, x, y);
if (type == STBTT_vcubic) {
@ -1137,7 +1137,7 @@ class StbTruetype {
stbtt__csctx_v(ctx, STBTT_vline, Std.int(ctx.x), Std.int(ctx.y), 0, 0, 0, 0);
}
private static inline function stbtt__csctx_rccurve_to(ctx: Stbtt__csctx, dx1: Float, dy1: Float, dx2: Float, dy2: Float, dx3: Float, dy3: Float): Void {
private static function stbtt__csctx_rccurve_to(ctx: Stbtt__csctx, dx1: Float, dy1: Float, dx2: Float, dy2: Float, dx3: Float, dy3: Float): Void {
var cx1: Float = ctx.x + dx1;
var cy1: Float = ctx.y + dy1;
var cx2: Float = cx1 + dx2;
@ -1147,7 +1147,7 @@ class StbTruetype {
stbtt__csctx_v(ctx, STBTT_vcubic, Std.int(ctx.x), Std.int(ctx.y), Std.int(cx1), Std.int(cy1), Std.int(cx2), Std.int(cy2));
}
private static inline function stbtt__get_subr(idx: Stbtt__buf, n: Int): Stbtt__buf
private static inline function stbtt__get_subr(idx: Stbtt__buf, n: Int): Stbtt__buf
{
var count: Int = stbtt__cff_index_count(idx);
var bias: Int = 107;
@ -1161,7 +1161,7 @@ class StbTruetype {
return stbtt__cff_index_get(idx, n);
}
private static inline function stbtt__cid_get_glyph_subrs(info: Stbtt_fontinfo, glyph_index: Int): Stbtt__buf {
private static function stbtt__cid_get_glyph_subrs(info: Stbtt_fontinfo, glyph_index: Int): Stbtt__buf {
var fdselect: Stbtt__buf = info.fdselect;
var nranges: Int, start, end, v, fmt, fdselector = -1, i;
@ -1197,12 +1197,12 @@ class StbTruetype {
var maskbits: Int = 0, subr_stack_height: Int = 0, sp: Int = 0, v: Int, i: Int, b0: Int;
var has_subrs: Bool = false, clear_stack;
var s: Array<Float> = [for (i in 0...48) 0];
var subr_stack: Array<Stbtt__buf> = [for (i in 0...10) new Stbtt__buf()];
var subrs: Stbtt__buf = info.subrs, b;
var subr_stack: Array<Stbtt__buf> = [for (i in 0...10) new Stbtt__buf(null, 0)];
var subrs: Stbtt__buf = info.subrs;
var f: Float;
// this currently ignores the initial width value, which isn't needed if we have hmtx
b = stbtt__cff_index_get(info.charstrings, glyph_index);
var b: Stbtt__buf = stbtt__cff_index_get(info.charstrings, glyph_index);
while (b.cursor < b.data.length) {
i = 0;
clear_stack = true;
@ -1661,7 +1661,7 @@ class StbTruetype {
if (x0 <= x && x1 <= x)
scanline[scanlineIndex + x] += e.direction * (y1-y0);
else if (x0 >= x + 1 && x1 >= x + 1) {
} else {
STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
scanline[scanlineIndex + x] += e.direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position
@ -1870,7 +1870,7 @@ class StbTruetype {
step.parent.next = z.next;
step.value = z.next;
}
STBTT_assert(z.direction != 0);
z.direction = 0;
} else {
@ -1900,7 +1900,7 @@ class StbTruetype {
}
++eIndex;
}
// now process all active edges
if (active != null)
stbtt__fill_active_edges_new(scanline, scanline2, scanline2Index + 1, result.w, active, scan_y_top);
@ -2260,7 +2260,7 @@ class StbTruetype {
iy0 = rect.y0;
ix1 = rect.x1;
iy1 = rect.y1;
// now we get the size
gbm.w = (ix1 - ix0);
gbm.h = (iy1 - iy0);
@ -2270,7 +2270,7 @@ class StbTruetype {
region.height = gbm.h;
region.xoff = ix0;
region.yoff = iy0;
if (gbm.w != 0 && gbm.h != 0) {
gbm.pixels = Blob.alloc(gbm.w * gbm.h);
if (gbm.pixels != null) {
@ -2311,7 +2311,7 @@ class StbTruetype {
public static function stbtt_GetCodepointBitmapSubpixel(info: Stbtt_fontinfo, scale_x: Float, scale_y: Float, shift_x: Float, shift_y: Float, codepoint: Int, region: Stbtt_temp_region): Blob {
return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), region);
}
}
public static function stbtt_MakeCodepointBitmapSubpixel(info: Stbtt_fontinfo, output: Blob, output_offset: Int, out_w: Int, out_h: Int, out_stride: Int, scale_x: Float, scale_y: Float, shift_x: Float, shift_y: Float, codepoint: Int): Void {
stbtt_MakeGlyphBitmapSubpixel(info, output, output_offset, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
@ -2319,7 +2319,7 @@ class StbTruetype {
public static function stbtt_GetCodepointBitmap(info: Stbtt_fontinfo, scale_x: Float, scale_y: Float, codepoint: Int, region: Stbtt_temp_region): Blob {
return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0, 0.0, codepoint, region);
}
}
public static function stbtt_MakeCodepointBitmap(info: Stbtt_fontinfo, output: Blob, output_offset: Int, out_w: Int, out_h: Int, out_stride: Int, scale_x: Float, scale_y: Float, codepoint: Int): Void {
stbtt_MakeCodepointBitmapSubpixel(info, output, output_offset, out_w, out_h, out_stride, scale_x, scale_y, 0.0, 0.0, codepoint);
@ -2462,7 +2462,7 @@ static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *no
con->y = 0;
con->bottom_y = 0;
STBTT__NOTUSED(nodes);
STBTT__NOTUSED(num_nodes);
STBTT__NOTUSED(num_nodes);
}
static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
@ -2812,7 +2812,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
n = 0;
for (i=0; i < num_ranges; ++i)
n += ranges[i].num_chars;
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
if (rects == NULL)
return 0;
@ -2822,7 +2822,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
stbtt_PackFontRangesPackRects(spc, rects, n);
return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
STBTT_free(rects, spc->user_allocator_context);
@ -2875,7 +2875,7 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, i
//
// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2)
static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2)
{
stbtt_int32 i=0;
@ -2914,7 +2914,7 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8
return i;
}
STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
{
return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2);
}

View File

@ -1,4 +1,4 @@
package kha.compute;
package kha.graphics4;
import kha.Blob;

View File

@ -53,6 +53,10 @@ interface Graphics {
function setPipeline(pipeline: PipelineState): Void;
function setShaderStorageBuffer(buffer: ShaderStorageBuffer, index: Int): Void;
function setComputeShader(shader: ComputeShader): Void;
function compute(x: Int, y: Int, z: Int): Void;
function setBool(location: ConstantLocation, value: Bool): Void;
function setInt(location: ConstantLocation, value: Int): Void;
function setInt2(location: ConstantLocation, value1: Int, value2: Int): Void;

View File

@ -413,7 +413,7 @@ class ColoredShaderPainter {
triangleIndexBuffer = new IndexBuffer(triangleBufferSize * 3, Usage.StaticUsage);
var triIndices = triangleIndexBuffer.lock();
for (i in 0...bufferSize) {
for (i in 0...triangleBufferSize) {
triIndices[i * 3 + 0] = i * 3 + 0;
triIndices[i * 3 + 1] = i * 3 + 1;
triIndices[i * 3 + 2] = i * 3 + 2;

View File

@ -1,6 +1,4 @@
package kha.compute;
import kha.graphics4.VertexData;
package kha.graphics4;
extern class ShaderStorageBuffer {
public function new(indexCount: Int, type: VertexData);

View File

@ -5,53 +5,61 @@ package kha.input;
class Gamepad {
var index: Int;
public static function get(index: Int = 0): Gamepad {
public static function get(index: Int = 0): Null<Gamepad> {
if (index >= instances.length)
return null;
return instances[index];
}
public static function notifyOnConnect(?connectListener: Int->Void, ?disconnectListener: Int->Void): Void {
/**
Use this event to get connected gamepad `index` and listen to it with `Gamepad.get(index).notify(axisListener, buttonListener)`.
Remember to also check `Gamepad.get(0)`, gamepads may already be connected before the application was initialized.
**/
public static function notifyOnConnect(?connectListener: (index: Int) -> Void, ?disconnectListener: (index: Int) -> Void): Void {
if (connectListener != null)
connectListeners.push(connectListener);
if (disconnectListener != null)
disconnectListeners.push(disconnectListener);
}
public static function removeConnect(?connectListener: Int->Void, ?disconnectListener: Int->Void): Void {
public static function removeConnect(?connectListener: (index: Int) -> Void, ?disconnectListener: (index: Int) -> Void): Void {
if (connectListener != null)
connectListeners.remove(connectListener);
if (disconnectListener != null)
disconnectListeners.remove(disconnectListener);
}
public function notify(?axisListener: Int->Float->Void, ?buttonListener: Int->Float->Void): Void {
/**
In `axisListener`, `axisId` is axis id (for example `axis == 0` is L-stick `x`, `1` is L-stick `y`, `2` is R-stick `x`, `3` is R-stick `y`, ...) and `value` is in `-1.0 - 1.0` range.
In `buttonListener`, `buttonId` is pressed button id (layout depends on `vendor`), and `value` is in `0 - 1.0` range how hard the button is pressed.
**/
public function notify(?axisListener: (axisId: Int, value: Float) -> Void, ?buttonListener: (buttonId: Int, value: Float) -> Void): Void {
if (axisListener != null)
axisListeners.push(axisListener);
if (buttonListener != null)
buttonListeners.push(buttonListener);
}
public function remove(?axisListener: Int->Float->Void, ?buttonListener: Int->Float->Void): Void {
public function remove(?axisListener: (axisId: Int, value: Float) -> Void, ?buttonListener: (buttonId: Int, value: Float) -> Void): Void {
if (axisListener != null)
axisListeners.remove(axisListener);
if (buttonListener != null)
buttonListeners.remove(buttonListener);
}
static var instances: Array<Gamepad> = new Array();
static var instances: Array<Gamepad> = [];
var axisListeners: Array<Int->Float->Void>;
var buttonListeners: Array<Int->Float->Void>;
var axisListeners: Array<(axisId: Int, value: Float) -> Void> = [];
var buttonListeners: Array<(buttonId: Int, value: Float) -> Void> = [];
static var connectListeners: Array<Int->Void> = new Array();
static var disconnectListeners: Array<Int->Void> = new Array();
static var connectListeners: Array<(index: Int) -> Void> = [];
static var disconnectListeners: Array<(index: Int) -> Void> = [];
function new(index: Int = 0, id: String = "unknown") {
connected = false;
this.index = index;
axisListeners = new Array<Int->Float->Void>();
buttonListeners = new Array<Int->Float->Void>();
instances[index] = this;
}

View File

@ -12,6 +12,12 @@ enum TouchDownEventBlockBehavior {
class Surface {
static var touchDownEventBlockBehavior = TouchDownEventBlockBehavior.Full;
/**
Sets to `true` after first `surface.notify` call,
so touch events will not be duplicated as `Mouse` events.
**/
static var listenedEventsBefore = false;
/**
* Get current Surface.
* @param num (optional) surface id (0 by default).
@ -41,6 +47,7 @@ class Surface {
*/
public function notify(?touchStartListener: (id: Int, x: Int, y: Int) -> Void, ?touchEndListener: (id: Int, x: Int, y: Int) -> Void,
?moveListener: (id: Int, x: Int, y: Int) -> Void): Void {
listenedEventsBefore = true;
if (touchStartListener != null)
touchStartListeners.push(touchStartListener);
if (touchEndListener != null)

View File

@ -6,13 +6,17 @@ import haxe.macro.Context;
import haxe.macro.Expr;
#if macro
import sys.io.File;
import sys.FileSystem;
#end
using StringTools;
class AssetsBuilder {
#if macro
public static var files: Array<Dynamic>;
@:persistent static var cache: Map<String, {time: Float, fields: Array<Field>}> = [];
@:persistent static var files: Array<Dynamic>;
@:persistent static var filesTime: Float = 0.0;
static var debug = false;
#end
public static function findResources(): String {
@ -51,29 +55,48 @@ class AssetsBuilder {
}
macro static public function build(type: String): Array<Field> {
var fields = Context.getBuildFields();
if (files == null) {
var content = Json.parse(File.getContent(findResources() + "files.json"));
files = content.files;
final fields = Context.getBuildFields();
final resPath = findResources() + "files.json";
Context.registerModuleDependency(Context.getLocalModule(), resPath);
final time = FileSystem.stat(resPath).mtime.getTime();
if (cache[type] != null && cache[type].time == time) {
return cache[type].fields;
}
var names = new Array<Expr>();
if (files == null || filesTime != time) {
final content = Json.parse(File.getContent(resPath));
files = content.files;
filesTime = time;
if (debug)
trace("reparse files.json (Assets)");
}
if (debug)
trace('invalidate Assets.$type');
final names = new Array<Expr>();
for (file in files) {
var name = file.name;
final name = file.name;
final pos = Context.currentPos();
var filesize: Int = file.file_sizes[0];
final filesize: Int = file.file_sizes[0];
if (file.type == type) {
names.push(macro $v{name});
switch (type) {
case "image":
var output = Compiler.getOutput();
output = output.replace("\\", "/");
output = output.substring(0, output.lastIndexOf("/"));
final path = '$output/${file.files[0]}';
final url = makeFileUrl(path);
fields.push({
name: name,
meta: [{pos: pos, name: ":keep"}],
access: [APublic],
kind: FVar(macro : kha.Image, macro null),
doc: '[![$url]($url)]($url)',
pos: pos
});
case "sound":
@ -129,7 +152,7 @@ class AssetsBuilder {
fields.push({
name: name + "Size",
doc: null,
meta: [],
meta: [{pos: pos, name: ":keep"}],
access: [APublic],
kind: FVar(macro : Dynamic, macro $v{filesize}),
pos: Context.currentPos()
@ -210,7 +233,20 @@ class AssetsBuilder {
kind: FVar(macro : Array<String>, macro $a{names}),
pos: Context.currentPos()
});
cache[type] = {
fields: fields,
time: time,
};
return fields;
}
#if macro
/** Converts a filesystem path into a `file://` URL safe for IDE hover previews. **/
static function makeFileUrl(path:String):String {
final absPath = FileSystem.absolutePath(path).replace("\\", "/");
final url = absPath.urlEncode().replace("%2F", "/").replace("%3A", ":");
return "file://" + (url.startsWith("/") ? "" : "/") + url;
}
#end
}

View File

@ -6,25 +6,32 @@ import haxe.macro.Expr.Field;
import haxe.Serializer;
#if macro
import sys.io.File;
import sys.FileSystem;
#end
using StringTools;
class ShadersBuilder {
#if macro
public static var files: Array<Dynamic>;
@:persistent static var cache: {time: Float, fields: Array<Field>} = null;
static var debug = false;
#end
macro static public function build(): Array<Field> {
var fields = Context.getBuildFields();
var manifestPath = AssetsBuilder.findResources() + "files.json";
var content = Json.parse(File.getContent(manifestPath));
final fields = Context.getBuildFields();
final manifestPath = AssetsBuilder.findResources() + "files.json";
// rebuild Shaders module whenever manifest file is changed
Context.registerModuleDependency(Context.getLocalModule(), manifestPath);
files = content.files;
final time = FileSystem.stat(manifestPath).mtime.getTime();
if (cache != null && time == cache.time) {
return cache.fields;
}
final content = Json.parse(File.getContent(manifestPath));
final files: Array<Dynamic> = content.files;
if (debug)
trace("invalidate Shaders");
var init = macro {};
@ -56,7 +63,7 @@ class ShadersBuilder {
doc: null,
meta: [],
access: [APublic, AStatic],
kind: FVar(macro : kha.compute.Shader, macro null),
kind: FVar(macro : kha.graphics4.ComputeShader, macro null),
pos: Context.currentPos()
});
@ -69,7 +76,7 @@ class ShadersBuilder {
var bytes: haxe.io.Bytes = haxe.Unserializer.run(data);
blobs.push(kha.Blob.fromBytes(bytes));
}
$i{fixedName} = new kha.compute.Shader(blobs, $v{filenames});
$i{fixedName} = new kha.graphics4.ComputeShader(blobs, $v{filenames});
}
};
}
@ -204,6 +211,10 @@ class ShadersBuilder {
}),
pos: Context.currentPos()
});
cache = {
fields: fields,
time: time,
};
return fields;
}