2
0
Эх сурвалжийг харах

Merge branch 'master' into windows-llvm-11.1.0

gingerBill 3 жил өмнө
parent
commit
3cb3d2cee4

+ 14 - 17
core/math/math.odin

@@ -607,9 +607,9 @@ floor_mod :: proc "contextless" (x, y: $T) -> T
 }
 
 modf_f16   :: proc "contextless" (x: f16) -> (int: f16, frac: f16) {
-	shift :: 16 - 5 - 1
-	mask  :: 0x1f
-	bias  :: 15
+	shift :: F16_SHIFT
+	mask  :: F16_MASK
+	bias  :: F16_BIAS
 
 	if x < 1 {
 		switch {
@@ -641,9 +641,9 @@ modf_f16be :: proc "contextless" (x: f16be) -> (int: f16be, frac: f16be) {
 	return f16be(i), f16be(f)
 }
 modf_f32   :: proc "contextless" (x: f32) -> (int: f32, frac: f32) {
-	shift :: 32 - 8 - 1
-	mask  :: 0xff
-	bias  :: 127
+	shift :: F32_SHIFT
+	mask  :: F32_MASK
+	bias  :: F32_BIAS
 
 	if x < 1 {
 		switch {
@@ -674,10 +674,10 @@ modf_f32be :: proc "contextless" (x: f32be) -> (int: f32be, frac: f32be) {
 	i, f := #force_inline modf_f32(f32(x))
 	return f32be(i), f32be(f)
 }
-modf_f64   :: proc "contextless" (x: f64) -> (int: f64, frac: f64) {
-	shift :: 64 - 11 - 1
-	mask  :: 0x7ff
-	bias  :: 1023
+modf_f64 :: proc "contextless" (x: f64) -> (int: f64, frac: f64) {
+	shift :: F64_SHIFT
+	mask  :: F64_MASK
+	bias  :: F64_BIAS
 
 	if x < 1 {
 		switch {
@@ -708,7 +708,7 @@ modf_f64be :: proc "contextless" (x: f64be) -> (int: f64be, frac: f64be) {
 	i, f := #force_inline modf_f64(f64(x))
 	return f64be(i), f64be(f)
 }
-modf       :: proc{
+modf :: proc{
 	modf_f16, modf_f16le, modf_f16be,
 	modf_f32, modf_f32le, modf_f32be,
 	modf_f64, modf_f64le, modf_f64be,
@@ -1127,13 +1127,11 @@ inf_f32be :: proc "contextless" (sign: int) -> f32be {
 	return f32be(inf_f64(sign))
 }
 inf_f64   :: proc "contextless" (sign: int) -> f64 {
-	v: u64
 	if sign >= 0 {
-		v = 0x7ff00000_00000000
+		return 0h7ff00000_00000000
 	} else {
-		v = 0xfff00000_00000000
+		return 0hfff00000_00000000
 	}
-	return transmute(f64)v
 }
 inf_f64le :: proc "contextless" (sign: int) -> f64le {
 	return f64le(inf_f64(sign))
@@ -1161,8 +1159,7 @@ nan_f32be :: proc "contextless" () -> f32be {
 	return f32be(nan_f64())
 }
 nan_f64   :: proc "contextless" () -> f64 {
-	v: u64 = 0x7ff80000_00000001
-	return transmute(f64)v
+	return 0h7ff80000_00000001
 }
 nan_f64le :: proc "contextless" () -> f64le {
 	return f64le(nan_f64())

+ 13 - 1
core/math/math_basic_js.odin

@@ -39,4 +39,16 @@ cos_f32     :: proc "c" (θ: f32) -> f32             { return f32(cos_f64(f64(θ
 pow_f32     :: proc "c" (x, power: f32) -> f32      { return f32(pow_f64(f64(x), f64(power)))         }
 fmuladd_f32 :: proc "c" (a, b, c: f32) -> f32       { return f32(fmuladd_f64(f64(a), f64(a), f64(c))) }
 ln_f32      :: proc "c" (x: f32) -> f32             { return f32(ln_f64(f64(x)))                      }
-exp_f32     :: proc "c" (x: f32) -> f32             { return f32(exp_f64(f64(x)))                     }
+exp_f32     :: proc "c" (x: f32) -> f32             { return f32(exp_f64(f64(x)))                     }
+
+ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
+ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
+ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
+ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
+ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
+ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
+ln :: proc{
+	ln_f16, ln_f16le, ln_f16be,
+	ln_f32, ln_f32le, ln_f32be,
+	ln_f64, ln_f64le, ln_f64be,
+}

+ 9 - 9
core/math/math_gamma.odin

@@ -68,17 +68,17 @@ package math
 @(private="file")
 stirling :: proc "contextless" (x: f64) -> (f64, f64) {
 	@(static) gamS := [?]f64{
-		7.87311395793093628397e-04,
+		+7.87311395793093628397e-04,
 		-2.29549961613378126380e-04,
 		-2.68132617805781232825e-03,
-		3.47222221605458667310e-03,
-		8.33333333333482257126e-02,
+		+3.47222221605458667310e-03,
+		+8.33333333333482257126e-02,
 	}
 	
 	if x > 200 {
 		return inf_f64(1), 1
 	}
-	SQRT_TWO_PI :: 2.506628274631000502417
+	SQRT_TWO_PI :: 0h40040d931ff62706 // 2.506628274631000502417
 	MAX_STIRLING :: 143.01608
 	w := 1 / x
 	w = 1 + w*((((gamS[0]*w+gamS[1])*w+gamS[2])*w+gamS[3])*w+gamS[4])
@@ -113,13 +113,13 @@ gamma_f64 :: proc "contextless" (x: f64) -> f64 {
 	}
 	@(static) gamQ := [?]f64{
 		-2.31581873324120129819e-05,
-		5.39605580493303397842e-04,
+		+5.39605580493303397842e-04,
 		-4.45641913851797240494e-03,
-		1.18139785222060435552e-02,
-		3.58236398605498653373e-02,
+		+1.18139785222060435552e-02,
+		+3.58236398605498653373e-02,
 		-2.34591795718243348568e-01,
-		7.14304917030273074085e-02,
-		1.00000000000000000320e+00,
+		+7.14304917030273074085e-02,
+		+1.00000000000000000320e+00,
 	}
 
 	

+ 4 - 4
core/math/math_lgamma.odin

@@ -197,9 +197,9 @@ lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
 	}
 
 	
-	Y_MIN  :: 1.461632144968362245
+	Y_MIN  :: 0h3ff762d86356be3f // 1.461632144968362245
 	TWO_52 :: 0h4330000000000000 // ~4.5036e+15
-	TWO_53  :: 0h4340000000000000 // ~9.0072e+15
+	TWO_53 :: 0h4340000000000000 // ~9.0072e+15
 	TWO_58 :: 0h4390000000000000 // ~2.8823e+17
 	TINY   :: 0h3b90000000000000 // ~8.47033e-22
 	Tc     :: 0h3FF762D86356BE3F
@@ -345,8 +345,8 @@ lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
 }
 
 
-lgamma_f16 :: proc "contextless" (x: f16) -> (lgamma: f16, sign: int) { r, s := lgamma_f64(f64(x)); return f16(r), s }
-lgamma_f32 :: proc "contextless" (x: f32) -> (lgamma: f32, sign: int) { r, s := lgamma_f64(f64(x)); return f32(r), s }
+lgamma_f16   :: proc "contextless" (x: f16)   -> (lgamma: f16, sign: int)   { r, s := lgamma_f64(f64(x)); return f16(r), s }
+lgamma_f32   :: proc "contextless" (x: f32)   -> (lgamma: f32, sign: int)   { r, s := lgamma_f64(f64(x)); return f32(r), s }
 lgamma_f16le :: proc "contextless" (x: f16le) -> (lgamma: f16le, sign: int) { r, s := lgamma_f64(f64(x)); return f16le(r), s }
 lgamma_f16be :: proc "contextless" (x: f16be) -> (lgamma: f16be, sign: int) { r, s := lgamma_f64(f64(x)); return f16be(r), s }
 lgamma_f32le :: proc "contextless" (x: f32le) -> (lgamma: f32le, sign: int) { r, s := lgamma_f64(f64(x)); return f32le(r), s }

+ 9 - 9
core/math/math_log1p.odin

@@ -100,11 +100,11 @@ log1p_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(log1p_f64(f
 log1p_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(log1p_f64(f64(x))) }
 
 log1p_f64 :: proc "contextless" (x: f64) -> f64 {
-	SQRT2_M1      :: 0h3fda827999fcef34 // Sqrt(2)-1 
-	SQRT2_HALF_M1 :: 0hbfd2bec333018866 // Sqrt(2)/2-1
+	SQRT2_M1      :: 0h3fda827999fcef34 // sqrt(2)-1 
+	SQRT2_HALF_M1 :: 0hbfd2bec333018866 // sqrt(2)/2-1
 	SMALL         :: 0h3e20000000000000 // 2**-29
-	TINY          :: 1.0 / (1 << 54)    // 2**-54
-	TWO53         :: 1 << 53            // 2**53
+	TINY          :: 0h3c90000000000000 // 2**-54
+	TWO53         :: 0h4340000000000000 // 2**53
 	LN2HI         :: 0h3fe62e42fee00000
 	LN2LO         :: 0h3dea39ef35793c76
 	LP1           :: 0h3FE5555555555593
@@ -128,15 +128,15 @@ log1p_f64 :: proc "contextless" (x: f64) -> f64 {
 	f: f64
 	iu: u64
 	k := 1
-	if absx < SQRT2_M1 { //  |x| < Sqrt(2)-1
+	if absx < SQRT2_M1 { //  |x| < sqrt(2)-1
 		if absx < SMALL { // |x| < 2**-29
 			if absx < TINY { // |x| < 2**-54
 				return x
 			}
 			return x - x*x*0.5
 		}
-		if x > SQRT2_HALF_M1 { // Sqrt(2)/2-1 < x
-			// (Sqrt(2)/2-1) < x < (Sqrt(2)-1)
+		if x > SQRT2_HALF_M1 { // sqrt(2)/2-1 < x
+			// (sqrt(2)/2-1) < x < (sqrt(2)-1)
 			k = 0
 			f = x
 			iu = 1
@@ -163,14 +163,14 @@ log1p_f64 :: proc "contextless" (x: f64) -> f64 {
 			c = 0
 		}
 		iu &= 0x000fffffffffffff
-		if iu < 0x0006a09e667f3bcd { // mantissa of Sqrt(2)
+		if iu < 0x0006a09e667f3bcd { // mantissa of sqrt(2)
 			u = transmute(f64)(iu | 0x3ff0000000000000) // normalize u
 		} else {
 			k += 1
 			u = transmute(f64)(iu | 0x3fe0000000000000) // normalize u/2
 			iu = (0x0010000000000000 - iu) >> 2
 		}
-		f = u - 1.0 // Sqrt(2)/2 < u < Sqrt(2)
+		f = u - 1.0 // sqrt(2)/2 < u < sqrt(2)
 	}
 	hfsq := 0.5 * f * f
 	s, R, z: f64

+ 1 - 1
core/odin/doc-format/doc_format.odin

@@ -11,7 +11,7 @@ String :: distinct Array(byte)
 
 Version_Type_Major :: 0
 Version_Type_Minor :: 2
-Version_Type_Patch :: 0
+Version_Type_Patch :: 1
 
 Version_Type :: struct {
 	major, minor, patch: u8,

+ 1 - 1
core/path/path.odin

@@ -150,7 +150,7 @@ join :: proc(elems: ..string, allocator := context.allocator) -> string {
 	context.allocator = allocator
 	for elem, i in elems {
 		if elem != "" {
-			s := strings.join(elems[i:], "/")
+			s := strings.join(elems[i:], "/", context.temp_allocator)
 			return clean(s)
 		}
 	}

+ 3 - 2
src/docs_format.cpp

@@ -15,7 +15,7 @@ struct OdinDocVersionType {
 
 #define OdinDocVersionType_Major 0
 #define OdinDocVersionType_Minor 2
-#define OdinDocVersionType_Patch 0
+#define OdinDocVersionType_Patch 1
 
 struct OdinDocHeaderBase {
 	u8                 magic[8];
@@ -175,7 +175,8 @@ enum OdinDocEntityFlag : u64 {
 
 struct OdinDocEntity {
 	OdinDocEntityKind  kind;
-	u32                flags;
+	u32                reserved;
+	u64                flags;
 	OdinDocPosition    pos;
 	OdinDocString      name;
 	OdinDocTypeIndex   type;

+ 1 - 1
vendor/OpenGL/constants.odin

@@ -1409,4 +1409,4 @@ TRANSFORM_FEEDBACK_OVERFLOW    :: 0x82EC
 TRANSFORM_FEEDBACK_STREAM_OVERFLOW :: 0x82ED
 
 // Extensions, extended as necessary
-DEVICE_LUID_EXT :: 0x9599;
+DEVICE_LUID_EXT :: 0x9599

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 702 - 702
vendor/OpenGL/wrappers.odin


+ 1 - 0
vendor/glfw/bindings/bindings.odin

@@ -4,6 +4,7 @@ import "core:c"
 import vk "vendor:vulkan"
 
 when ODIN_OS == "linux"   { foreign import glfw "system:glfw" } // TODO: Add the billion-or-so static libs to link to in linux
+when ODIN_OS == "darwin"  { foreign import glfw "system:glfw" }
 when ODIN_OS == "windows" { 
 	foreign import glfw { 
 		"../lib/glfw3_mt.lib",

+ 177 - 163
vendor/portmidi/portmidi.odin

@@ -3,7 +3,13 @@ package portmidi
 import "core:c"
 import "core:strings"
 
-when ODIN_OS == "windows" { foreign import lib "portmidi.lib" }
+when ODIN_OS == "windows" { 
+	foreign import lib {
+		"portmidi_s.lib",
+		"system:Winmm.lib",
+		"system:Advapi32.lib",
+	}
+}
 
 #assert(size_of(b32) == size_of(c.int))
 
@@ -15,17 +21,17 @@ Error :: enum c.int {
 	GotData = 1, /**< A "no error" return that also indicates data available */
 	HostError = -10000,
 	InvalidDeviceId, /** out of range or 
-		            * output device when input is requested or 
-		            * input device when output is requested or
-		            * device is already opened 
-		            */
+	                   * output device when input is requested or 
+	                   * input device when output is requested or
+	                   * device is already opened 
+	                   */
 	InsufficientMemory,
 	BufferTooSmall,
 	BufferOverflow,
 	BadPtr, /* Stream parameter is nil or
-		     * stream is not opened or
-		     * stream is output when input is required or
-		     * stream is input when output is required */
+	         * stream is not opened or
+	         * stream is output when input is required or
+	         * stream is input when output is required */
 	BadData, /** illegal midi data, e.g. missing EOX */
 	InternalError,
 	BufferMaxSize, /** buffer is already as large as it can be */
@@ -38,30 +44,30 @@ Stream :: distinct rawptr
 @(default_calling_convention="c", link_prefix="Pm_")
 foreign lib {
 	/**
-	    Initialize() is the library initialisation function - call this before
-	    using the library.
+		Initialize() is the library initialisation function - call this before
+		using the library.
 	*/
 	Initialize :: proc() -> Error ---
 	
 	/**
-	    Terminate() is the library termination function - call this after
-	    using the library.
+		Terminate() is the library termination function - call this after
+		using the library.
 	*/
 	Terminate  :: proc() -> Error ---
 	
 	/**
-	    Test whether stream has a pending host error. Normally, the client finds
-	    out about errors through returned error codes, but some errors can occur
-	    asynchronously where the client does not
-	    explicitly call a function, and therefore cannot receive an error code.
-	    The client can test for a pending error using HasHostError(). If true,
-	    the error can be accessed and cleared by calling GetErrorText(). 
-	    Errors are also cleared by calling other functions that can return
-	    errors, e.g. OpenInput(), OpenOutput(), Read(), Write(). The
-	    client does not need to call HasHostError(). Any pending error will be
-	    reported the next time the client performs an explicit function call on 
-	    the stream, e.g. an input or output operation. Until the error is cleared,
-	    no new error codes will be obtained, even for a different stream.
+		Test whether stream has a pending host error. Normally, the client finds
+		out about errors through returned error codes, but some errors can occur
+		asynchronously where the client does not
+		explicitly call a function, and therefore cannot receive an error code.
+		The client can test for a pending error using HasHostError(). If true,
+		the error can be accessed and cleared by calling GetErrorText(). 
+		Errors are also cleared by calling other functions that can return
+		errors, e.g. OpenInput(), OpenOutput(), Read(), Write(). The
+		client does not need to call HasHostError(). Any pending error will be
+		reported the next time the client performs an explicit function call on 
+		the stream, e.g. an input or output operation. Until the error is cleared,
+		no new error codes will be obtained, even for a different stream.
 	*/
 	HasHostError :: proc(stream: Stream) -> b32 ---	
 }
@@ -103,8 +109,8 @@ DeviceInfo :: struct {
 	structVersion: c.int,   /**< this internal structure version */ 
 	interf:        cstring, /**< underlying MIDI API, e.g. MMSystem or DirectX */
 	name:          cstring, /**< device name, e.g. USB MidiSport 1x1 */
-	input:         c.int,   /**< true iff input is available */
-	output:        c.int,   /**< true iff output is available */
+	input:         b32,     /**< true iff input is available */
+	output:        b32,     /**< true iff output is available */
 	opened:        b32,     /**< used by generic PortMidi code to do error checking on arguments */
 }
 
@@ -132,79 +138,78 @@ Before :: #force_inline proc "c" (t1, t2: Timestamp) -> b32 {
 @(default_calling_convention="c", link_prefix="Pm_")
 foreign lib {
 	/**
-	    GetDeviceInfo() returns a pointer to a DeviceInfo structure
-	    referring to the device specified by id.
-	    If id is out of range the function returns nil.
+		GetDeviceInfo() returns a pointer to a DeviceInfo structure
+		referring to the device specified by id.
+		If id is out of range the function returns nil.
 
-	    The returned structure is owned by the PortMidi implementation and must
-	    not be manipulated or freed. The pointer is guaranteed to be valid
-	    between calls to Initialize() and Terminate().
+		The returned structure is owned by the PortMidi implementation and must
+		not be manipulated or freed. The pointer is guaranteed to be valid
+		between calls to Initialize() and Terminate().
 	*/
-	GetDeviceInfo :: proc(id: DeviceID) -> DeviceInfo ---
+	GetDeviceInfo :: proc(id: DeviceID) -> ^DeviceInfo ---
 	
 	/**
-	    OpenInput() and OpenOutput() open devices.
-
-	    stream is the address of a Stream pointer which will receive
-	    a pointer to the newly opened stream.
-
-	    inputDevice is the id of the device used for input (see DeviceID above).
-
-	    inputDriverInfo is a pointer to an optional driver specific data structure
-	    containing additional information for device setup or handle processing.
-	    inputDriverInfo is never required for correct operation. If not used
-	    inputDriverInfo should be nil.
-
-	    outputDevice is the id of the device used for output (see DeviceID above.)
-
-	    outputDriverInfo is a pointer to an optional driver specific data structure
-	    containing additional information for device setup or handle processing.
-	    outputDriverInfo is never required for correct operation. If not used
-	    outputDriverInfo should be nil.
-
-	    For input, the buffersize specifies the number of input events to be 
-	    buffered waiting to be read using Read(). For output, buffersize 
-	    specifies the number of output events to be buffered waiting for output. 
-	    (In some cases -- see below -- PortMidi does not buffer output at all
-	    and merely passes data to a lower-level API, in which case buffersize
-	    is ignored.)
-	    
-	    latency is the delay in milliseconds applied to timestamps to determine 
-	    when the output should actually occur. (If latency is < 0, 0 is assumed.) 
-	    If latency is zero, timestamps are ignored and all output is delivered
-	    immediately. If latency is greater than zero, output is delayed until the
-	    message timestamp plus the latency. (NOTE: the time is measured relative 
-	    to the time source indicated by time_proc. Timestamps are absolute,
-	    not relative delays or offsets.) In some cases, PortMidi can obtain
-	    better timing than your application by passing timestamps along to the
-	    device driver or hardware. Latency may also help you to synchronize midi
-	    data to audio data by matching midi latency to the audio buffer latency.
-
-	    time_proc is a pointer to a procedure that returns time in milliseconds. It
-	    may be nil, in which case a default millisecond timebase (PortTime) is 
-	    used. If the application wants to use PortTime, it should start the timer
-	    (call Pt_Start) before calling OpenInput or OpenOutput. If the
-	    application tries to start the timer *after* OpenInput or OpenOutput,
-	    it may get a ptAlreadyStarted error from Pt_Start, and the application's
-	    preferred time resolution and callback function will be ignored.
-	    time_proc result values are appended to incoming MIDI data, and time_proc
-	    times are used to schedule outgoing MIDI data (when latency is non-zero).
-
-	    time_info is a pointer passed to time_proc.
-
-	    Example: If I provide a timestamp of 5000, latency is 1, and time_proc
-	    returns 4990, then the desired output time will be when time_proc returns
-	    timestamp+latency = 5001. This will be 5001-4990 = 11ms from now.
-
-	    return value:
-	    Upon success Open() returns NoError and places a pointer to a
-	    valid Stream in the stream argument.
-	    If a call to Open() fails a nonzero error code is returned (see
-	    PMError above) and the value of port is invalid.
-
-	    Any stream that is successfully opened should eventually be closed
-	    by calling Close().
-
+		OpenInput() and OpenOutput() open devices.
+
+		stream is the address of a Stream pointer which will receive
+		a pointer to the newly opened stream.
+
+		inputDevice is the id of the device used for input (see DeviceID above).
+
+		inputDriverInfo is a pointer to an optional driver specific data structure
+		containing additional information for device setup or handle processing.
+		inputDriverInfo is never required for correct operation. If not used
+		inputDriverInfo should be nil.
+
+		outputDevice is the id of the device used for output (see DeviceID above.)
+
+		outputDriverInfo is a pointer to an optional driver specific data structure
+		containing additional information for device setup or handle processing.
+		outputDriverInfo is never required for correct operation. If not used
+		outputDriverInfo should be nil.
+
+		For input, the buffersize specifies the number of input events to be 
+		buffered waiting to be read using Read(). For output, buffersize 
+		specifies the number of output events to be buffered waiting for output. 
+		(In some cases -- see below -- PortMidi does not buffer output at all
+		and merely passes data to a lower-level API, in which case buffersize
+		is ignored.)
+
+		latency is the delay in milliseconds applied to timestamps to determine 
+		when the output should actually occur. (If latency is < 0, 0 is assumed.) 
+		If latency is zero, timestamps are ignored and all output is delivered
+		immediately. If latency is greater than zero, output is delayed until the
+		message timestamp plus the latency. (NOTE: the time is measured relative 
+		to the time source indicated by time_proc. Timestamps are absolute,
+		not relative delays or offsets.) In some cases, PortMidi can obtain
+		better timing than your application by passing timestamps along to the
+		device driver or hardware. Latency may also help you to synchronize midi
+		data to audio data by matching midi latency to the audio buffer latency.
+
+		time_proc is a pointer to a procedure that returns time in milliseconds. It
+		may be nil, in which case a default millisecond timebase (PortTime) is 
+		used. If the application wants to use PortTime, it should start the timer
+		(call Pt_Start) before calling OpenInput or OpenOutput. If the
+		application tries to start the timer *after* OpenInput or OpenOutput,
+		it may get a ptAlreadyStarted error from Pt_Start, and the application's
+		preferred time resolution and callback function will be ignored.
+		time_proc result values are appended to incoming MIDI data, and time_proc
+		times are used to schedule outgoing MIDI data (when latency is non-zero).
+
+		time_info is a pointer passed to time_proc.
+
+		Example: If I provide a timestamp of 5000, latency is 1, and time_proc
+		returns 4990, then the desired output time will be when time_proc returns
+		timestamp+latency = 5001. This will be 5001-4990 = 11ms from now.
+
+		return value:
+		Upon success Open() returns NoError and places a pointer to a
+		valid Stream in the stream argument.
+		If a call to Open() fails a nonzero error code is returned (see
+		PMError above) and the value of port is invalid.
+
+		Any stream that is successfully opened should eventually be closed
+		by calling Close().
 	*/
 	OpenInput :: proc(stream: ^Stream,
 	                  inputDevice: DeviceID,
@@ -373,71 +378,80 @@ MessageData2  :: #force_inline proc "c" (msg: Message) -> c.int {
 	return c.int((msg >> 16) & 0xFF)
 }
 
+MessageCompose :: MessageMake
+MessageDecompose :: #force_inline proc "c" (msg: Message) -> (status, data1, data2: c.int) {
+	status = c.int(msg & 0xFF)
+	data1  = c.int((msg >> 8) & 0xFF)
+	data2  = c.int((msg >> 16) & 0xFF)
+	return
+}
+
+
 Message :: distinct i32
 /**
-   All midi data comes in the form of Event structures. A sysex
-   message is encoded as a sequence of Event structures, with each
-   structure carrying 4 bytes of the message, i.e. only the first
-   Event carries the status byte.
-
-   Note that MIDI allows nested messages: the so-called "real-time" MIDI 
-   messages can be inserted into the MIDI byte stream at any location, 
-   including within a sysex message. MIDI real-time messages are one-byte
-   messages used mainly for timing (see the MIDI spec). PortMidi retains 
-   the order of non-real-time MIDI messages on both input and output, but 
-   it does not specify exactly how real-time messages are processed. This
-   is particulary problematic for MIDI input, because the input parser 
-   must either prepare to buffer an unlimited number of sysex message 
-   bytes or to buffer an unlimited number of real-time messages that 
-   arrive embedded in a long sysex message. To simplify things, the input
-   parser is allowed to pass real-time MIDI messages embedded within a 
-   sysex message, and it is up to the client to detect, process, and 
-   remove these messages as they arrive.
-
-   When receiving sysex messages, the sysex message is terminated
-   by either an EOX status byte (anywhere in the 4 byte messages) or
-   by a non-real-time status byte in the low order byte of the message.
-   If you get a non-real-time status byte but there was no EOX byte, it 
-   means the sysex message was somehow truncated. This is not
-   considered an error; e.g., a missing EOX can result from the user
-   disconnecting a MIDI cable during sysex transmission.
-
-   A real-time message can occur within a sysex message. A real-time 
-   message will always occupy a full Event with the status byte in 
-   the low-order byte of the Event message field. (This implies that
-   the byte-order of sysex bytes and real-time message bytes may not
-   be preserved -- for example, if a real-time message arrives after
-   3 bytes of a sysex message, the real-time message will be delivered
-   first. The first word of the sysex message will be delivered only
-   after the 4th byte arrives, filling the 4-byte Event message field.
-   
-   The timestamp field is observed when the output port is opened with
-   a non-zero latency. A timestamp of zero means "use the current time",
-   which in turn means to deliver the message with a delay of
-   latency (the latency parameter used when opening the output port.)
-   Do not expect PortMidi to sort data according to timestamps -- 
-   messages should be sent in the correct order, and timestamps MUST 
-   be non-decreasing. See also "Example" for OpenOutput() above.
-
-   A sysex message will generally fill many Event structures. On 
-   output to a Stream with non-zero latency, the first timestamp
-   on sysex message data will determine the time to begin sending the 
-   message. PortMidi implementations may ignore timestamps for the 
-   remainder of the sysex message. 
-   
-   On input, the timestamp ideally denotes the arrival time of the 
-   status byte of the message. The first timestamp on sysex message 
-   data will be valid. Subsequent timestamps may denote 
-   when message bytes were actually received, or they may be simply 
-   copies of the first timestamp.
-
-   Timestamps for nested messages: If a real-time message arrives in 
-   the middle of some other message, it is enqueued immediately with 
-   the timestamp corresponding to its arrival time. The interrupted 
-   non-real-time message or 4-byte packet of sysex data will be enqueued 
-   later. The timestamp of interrupted data will be equal to that of
-   the interrupting real-time message to insure that timestamps are
-   non-decreasing.
+	All midi data comes in the form of Event structures. A sysex
+	message is encoded as a sequence of Event structures, with each
+	structure carrying 4 bytes of the message, i.e. only the first
+	Event carries the status byte.
+
+	Note that MIDI allows nested messages: the so-called "real-time" MIDI 
+	messages can be inserted into the MIDI byte stream at any location, 
+	including within a sysex message. MIDI real-time messages are one-byte
+	messages used mainly for timing (see the MIDI spec). PortMidi retains 
+	the order of non-real-time MIDI messages on both input and output, but 
+	it does not specify exactly how real-time messages are processed. This
+	is particulary problematic for MIDI input, because the input parser 
+	must either prepare to buffer an unlimited number of sysex message 
+	bytes or to buffer an unlimited number of real-time messages that 
+	arrive embedded in a long sysex message. To simplify things, the input
+	parser is allowed to pass real-time MIDI messages embedded within a 
+	sysex message, and it is up to the client to detect, process, and 
+	remove these messages as they arrive.
+
+	When receiving sysex messages, the sysex message is terminated
+	by either an EOX status byte (anywhere in the 4 byte messages) or
+	by a non-real-time status byte in the low order byte of the message.
+	If you get a non-real-time status byte but there was no EOX byte, it 
+	means the sysex message was somehow truncated. This is not
+	considered an error; e.g., a missing EOX can result from the user
+	disconnecting a MIDI cable during sysex transmission.
+
+	A real-time message can occur within a sysex message. A real-time 
+	message will always occupy a full Event with the status byte in 
+	the low-order byte of the Event message field. (This implies that
+	the byte-order of sysex bytes and real-time message bytes may not
+	be preserved -- for example, if a real-time message arrives after
+	3 bytes of a sysex message, the real-time message will be delivered
+	first. The first word of the sysex message will be delivered only
+	after the 4th byte arrives, filling the 4-byte Event message field.
+
+	The timestamp field is observed when the output port is opened with
+	a non-zero latency. A timestamp of zero means "use the current time",
+	which in turn means to deliver the message with a delay of
+	latency (the latency parameter used when opening the output port.)
+	Do not expect PortMidi to sort data according to timestamps -- 
+	messages should be sent in the correct order, and timestamps MUST 
+	be non-decreasing. See also "Example" for OpenOutput() above.
+
+	A sysex message will generally fill many Event structures. On 
+	output to a Stream with non-zero latency, the first timestamp
+	on sysex message data will determine the time to begin sending the 
+	message. PortMidi implementations may ignore timestamps for the 
+	remainder of the sysex message. 
+
+	On input, the timestamp ideally denotes the arrival time of the 
+	status byte of the message. The first timestamp on sysex message 
+	data will be valid. Subsequent timestamps may denote 
+	when message bytes were actually received, or they may be simply 
+	copies of the first timestamp.
+
+	Timestamps for nested messages: If a real-time message arrives in 
+	the middle of some other message, it is enqueued immediately with 
+	the timestamp corresponding to its arrival time. The interrupted 
+	non-real-time message or 4-byte packet of sysex data will be enqueued 
+	later. The timestamp of interrupted data will be equal to that of
+	the interrupting real-time message to insure that timestamps are
+	non-decreasing.
  */
 Event :: struct {
 	message:   Message,
@@ -480,18 +494,18 @@ foreign lib {
 	
 	/** 
 		Write() writes midi data from a buffer. This may contain:
-		    - short messages 
+			- short messages 
 		or 
-		    - sysex messages that are converted into a sequence of Event
-		      structures, e.g. sending data from a file or forwarding them
-		      from midi input.
+			- sysex messages that are converted into a sequence of Event
+			  structures, e.g. sending data from a file or forwarding them
+			  from midi input.
 
 		Use WriteSysEx() to write a sysex message stored as a contiguous 
 		array of bytes.
 
 		Sysex data may contain embedded real-time messages.
 	*/
-	Write      :: proc(stream: Stream, buffer: [^]Event, length: i32) -> Error ---
+	Write :: proc(stream: Stream, buffer: [^]Event, length: i32) -> Error ---
 	
 	/**
 		WriteShort() writes a timestamped non-system-exclusive midi message.

BIN
vendor/portmidi/portmidi_s.lib


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно