v0.0.3 Build

This commit is contained in:
Ginger Bill
2016-11-17 22:58:00 +00:00
parent 4895031df5
commit 24ca106521
15 changed files with 2013 additions and 289 deletions

View File

@@ -4,7 +4,7 @@
set exe_name=odin.exe
:: Debug = 0, Release = 1
set release_mode=0
set release_mode=1
set compiler_flags= -nologo -Oi -TP -W4 -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
@@ -48,7 +48,7 @@ rem pushd %build_dir%
cl %compiler_settings% "src\main.cpp" ^
/link %linker_settings% -OUT:%exe_name% ^
&& odin run w:/Freyr/src/main.odin
&& odin run code/demo.odin
rem odin run code/demo.odin

View File

@@ -1,32 +1,6 @@
x: i64 = 123
Vec2 :: struct {
x, y: i64
}
#import "fmt.odin"
#import "game.odin"
main :: proc() {
foo :: proc() -> i64 {
bar :: proc() -> (i64, i64) {
a := [3]i64{7, 4, 2}
v := Vec2{a[0], 2}
return v.x, v.y
}
x, y := bar()
return x + y
}
test :: proc(s: string) -> string {
return s
}
foo()
x = test("Hello").count as i64
xp := ^x
p := xp^
z := [..]i64{1, 2, 3, 4}
z[0] = p
fmt.println("Hellope, everybody!")
}

View File

@@ -107,9 +107,7 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
0, // NOTE(bill): tells the proc that this is the end of attribs
}
wgl_string := "wglCreateContextAttribsARB\x00"
c_wgl_string := ^wgl_string[0]
wglCreateContextAttribsARB := wglGetProcAddress(c_wgl_string) as wglCreateContextAttribsARBType
wglCreateContextAttribsARB := wglGetProcAddress(("wglCreateContextAttribsARB\x00" as string).data) as wglCreateContextAttribsARBType
w.rc = wglCreateContextAttribsARB(w.dc, 0, ^attribs[0])
wglMakeCurrent(w.dc, w.rc)
SwapBuffers(w.dc)
@@ -145,6 +143,7 @@ run :: proc() {
}
defer destroy_window(^window)
gl.init()
prev_time := time_now()
@@ -205,7 +204,7 @@ run :: proc() {
gl.Color3f(1, 0, 0); gl.Vertex3f(x, y, 0)
}
draw_rect(pos[0], pos[1], 50, 50)
draw_rect(pos.x, pos.y, 50, 50)
display_window(^window)
ms_to_sleep := (16 - 1000*dt) as i32

View File

@@ -1,180 +0,0 @@
TAU :: 6.28318530717958647692528676655900576
PI :: 3.14159265358979323846264338327950288
ONE_OVER_TAU :: 0.636619772367581343075535053490057448
ONE_OVER_PI :: 0.159154943091895335768883763372514362
E :: 2.71828182845904523536
SQRT_TWO :: 1.41421356237309504880168872420969808
SQRT_THREE :: 1.73205080756887729352744634150587236
SQRT_FIVE :: 2.23606797749978969640917366873127623
LOG_TWO :: 0.693147180559945309417232121458176568
LOG_TEN :: 2.30258509299404568401799145468436421
EPSILON :: 1.19209290e-7
τ :: TAU
π :: PI
// Vec2 :: type raw_union {
// using xy_: struct {x, y: f32}
// v: {2}f32
// e: [2]f32
// }
// Vec3 :: type raw_union {
// using xyz_: struct {x, y, z: f32}
// xy: Vec2
// v: {3}f32
// e: [3]f32
// }
// Vec4 :: type raw_union {
// using xyzw_: struct {x, y, z, w: f32}
// xy: Vec2
// xyz: Vec3
// v: {4}f32
// e: [4]f32
// }
Vec2 :: type {2}f32
Vec3 :: type {3}f32
Vec4 :: type {4}f32
Mat2 :: type {4}f32
Mat3 :: type {9}f32
Mat4 :: type {16}f32
sqrt32 :: proc(x: f32) -> f32 #foreign "llvm.sqrt.f32"
sqrt64 :: proc(x: f64) -> f64 #foreign "llvm.sqrt.f64"
sin32 :: proc(x: f32) -> f32 #foreign "llvm.sin.f32"
sin64 :: proc(x: f64) -> f64 #foreign "llvm.sin.f64"
cos64 :: proc(x: f64) -> f64 #foreign "llvm.cos.f64"
cos32 :: proc(x: f32) -> f32 #foreign "llvm.cos.f32"
lerp32 :: proc(a, b, t: f32) -> f32 { return a*(1-t) + b*t }
lerp64 :: proc(a, b, t: f64) -> f64 { return a*(1-t) + b*t }
clamp32 :: proc(x, lower, upper: f32) -> f32 { return min(max(x, lower), upper) }
clamp64 :: proc(x, lower, upper: f64) -> f64 { return min(max(x, lower), upper) }
sign32 :: proc(x: f32) -> f32 { if x >= 0 { return +1 } return -1 }
sign64 :: proc(x: f64) -> f64 { if x >= 0 { return +1 } return -1 }
copy_sign :: proc(x, y: f32) -> f32 {
ix := x transmute u32
iy := y transmute u32
ix &= 0x7fffffff
ix |= iy & 0x80000000
return ix transmute f32
}
round :: proc(x: f32) -> f32 {
if x >= 0 {
return floor(x + 0.5)
}
return ceil(x - 0.5)
}
floor :: proc(x: f32) -> f32 {
if x >= 0 {
return x as int as f32
}
return (x-0.5) as int as f32
}
ceil :: proc(x: f32) -> f32 {
if x < 0 {
return x as int as f32
}
return ((x as int)+1) as f32
}
remainder :: proc(x, y: f32) -> f32 {
return x - round(x/y) * y
}
fmod :: proc(x, y: f32) -> f32 {
y = abs(y)
result := remainder(abs(x), y)
if sign32(result) < 0 {
result += y
}
return copy_sign(result, x)
}
to_radians :: proc(degrees: f32) -> f32 { return degrees * TAU / 360 }
to_degrees :: proc(radians: f32) -> f32 { return radians * 360 / TAU }
dot2 :: proc(a, b: Vec2) -> f32 { c := a*b; return c[0] + c[1] }
dot3 :: proc(a, b: Vec3) -> f32 { c := a*b; return c[0] + c[1] + c[2] }
dot4 :: proc(a, b: Vec4) -> f32 { c := a*b; return c[0] + c[1] + c[2] + c[3] }
cross :: proc(x, y: Vec3) -> Vec3 {
a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1)
b := swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0)
return a - b
}
vec2_mag :: proc(v: Vec2) -> f32 { return sqrt32(dot2(v, v)) }
vec3_mag :: proc(v: Vec3) -> f32 { return sqrt32(dot3(v, v)) }
vec4_mag :: proc(v: Vec4) -> f32 { return sqrt32(dot4(v, v)) }
vec2_norm :: proc(v: Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)} }
vec3_norm :: proc(v: Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)} }
vec4_norm :: proc(v: Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)} }
vec2_norm0 :: proc(v: Vec2) -> Vec2 {
m := vec2_mag(v)
if m == 0 {
return Vec2{0}
}
return v / Vec2{m}
}
vec3_norm0 :: proc(v: Vec3) -> Vec3 {
m := vec3_mag(v)
if m == 0 {
return Vec3{0}
}
return v / Vec3{m}
}
vec4_norm0 :: proc(v: Vec4) -> Vec4 {
m := vec4_mag(v)
if m == 0 {
return Vec4{0}
}
return v / Vec4{m}
}
F32_DIG :: 6
F32_EPSILON :: 1.192092896e-07
F32_GUARD :: 0
F32_MANT_DIG :: 24
F32_MAX :: 3.402823466e+38
F32_MAX_10_EXP :: 38
F32_MAX_EXP :: 128
F32_MIN :: 1.175494351e-38
F32_MIN_10_EXP :: -37
F32_MIN_EXP :: -125
F32_NORMALIZE :: 0
F32_RADIX :: 2
F32_ROUNDS :: 1
F64_DIG :: 15 // # of decimal digits of precision
F64_EPSILON :: 2.2204460492503131e-016 // smallest such that 1.0+F64_EPSILON != 1.0
F64_MANT_DIG :: 53 // # of bits in mantissa
F64_MAX :: 1.7976931348623158e+308 // max value
F64_MAX_10_EXP :: 308 // max decimal exponent
F64_MAX_EXP :: 1024 // max binary exponent
F64_MIN :: 2.2250738585072014e-308 // min positive value
F64_MIN_10_EXP :: -307 // min decimal exponent
F64_MIN_EXP :: -1021 // min binary exponent
F64_RADIX :: 2 // exponent radix
F64_ROUNDS :: 1 // addition rounding: near

View File

@@ -4,6 +4,7 @@
#import "fmt.odin"
#import "mem.odin"
/*
Optimization_Level :: enum {
DEBUG,
RELEASE,
@@ -24,7 +25,7 @@ Build_Options :: struct {
}
build_options: Build_Options
*/
// IMPORTANT NOTE(bill): Do not change the order of any of this data
// The compiler relies upon this _exact_ order
@@ -80,6 +81,7 @@ Type_Info :: union {
elem: ^Type_Info
elem_size: int
count: int
align: int
}
Tuple: Record
Struct: Record

373
core/math.odin Normal file
View File

@@ -0,0 +1,373 @@
TAU :: 6.28318530717958647692528676655900576
PI :: 3.14159265358979323846264338327950288
ONE_OVER_TAU :: 0.636619772367581343075535053490057448
ONE_OVER_PI :: 0.159154943091895335768883763372514362
E :: 2.71828182845904523536
SQRT_TWO :: 1.41421356237309504880168872420969808
SQRT_THREE :: 1.73205080756887729352744634150587236
SQRT_FIVE :: 2.23606797749978969640917366873127623
LOG_TWO :: 0.693147180559945309417232121458176568
LOG_TEN :: 2.30258509299404568401799145468436421
EPSILON :: 1.19209290e-7
τ :: TAU
π :: PI
Vec2 :: type {2}f32
Vec3 :: type {3}f32
Vec4 :: type {4}f32
Mat2 :: type [2]Vec2
Mat3 :: type [3]Vec3
Mat4 :: type [4]Vec4
sqrt32 :: proc(x: f32) -> f32 #foreign "llvm.sqrt.f32"
sqrt64 :: proc(x: f64) -> f64 #foreign "llvm.sqrt.f64"
sin32 :: proc(x: f32) -> f32 #foreign "llvm.sin.f32"
sin64 :: proc(x: f64) -> f64 #foreign "llvm.sin.f64"
cos32 :: proc(x: f32) -> f32 #foreign "llvm.cos.f32"
cos64 :: proc(x: f64) -> f64 #foreign "llvm.cos.f64"
tan32 :: proc(x: f32) -> f32 #inline { return sin32(x)/cos32(x) }
tan64 :: proc(x: f64) -> f64 #inline { return sin64(x)/cos64(x) }
lerp32 :: proc(a, b, t: f32) -> f32 { return a*(1-t) + b*t }
lerp64 :: proc(a, b, t: f64) -> f64 { return a*(1-t) + b*t }
clamp32 :: proc(x, lower, upper: f32) -> f32 { return min(max(x, lower), upper) }
clamp64 :: proc(x, lower, upper: f64) -> f64 { return min(max(x, lower), upper) }
sign32 :: proc(x: f32) -> f32 { if x >= 0 { return +1 } return -1 }
sign64 :: proc(x: f64) -> f64 { if x >= 0 { return +1 } return -1 }
copy_sign32 :: proc(x, y: f32) -> f32 {
ix := x transmute u32
iy := y transmute u32
ix &= 0x7fffffff
ix |= iy & 0x80000000
return ix transmute f32
}
round32 :: proc(x: f32) -> f32 {
if x >= 0 {
return floor32(x + 0.5)
}
return ceil32(x - 0.5)
}
floor32 :: proc(x: f32) -> f32 {
if x >= 0 {
return x as int as f32
}
return (x-0.5) as int as f32
}
ceil32 :: proc(x: f32) -> f32 {
if x < 0 {
return x as int as f32
}
return ((x as int)+1) as f32
}
remainder32 :: proc(x, y: f32) -> f32 {
return x - round32(x/y) * y
}
fmod32 :: proc(x, y: f32) -> f32 {
y = abs(y)
result := remainder32(abs(x), y)
if sign32(result) < 0 {
result += y
}
return copy_sign32(result, x)
}
to_radians :: proc(degrees: f32) -> f32 { return degrees * TAU / 360 }
to_degrees :: proc(radians: f32) -> f32 { return radians * 360 / TAU }
dot2 :: proc(a, b: Vec2) -> f32 { c := a*b; return c.x + c.y }
dot3 :: proc(a, b: Vec3) -> f32 { c := a*b; return c.x + c.y + c.z }
dot4 :: proc(a, b: Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w }
cross3 :: proc(x, y: Vec3) -> Vec3 {
a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1)
b := swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0)
return a - b
}
vec2_mag :: proc(v: Vec2) -> f32 { return sqrt32(dot2(v, v)) }
vec3_mag :: proc(v: Vec3) -> f32 { return sqrt32(dot3(v, v)) }
vec4_mag :: proc(v: Vec4) -> f32 { return sqrt32(dot4(v, v)) }
vec2_norm :: proc(v: Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)} }
vec3_norm :: proc(v: Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)} }
vec4_norm :: proc(v: Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)} }
vec2_norm0 :: proc(v: Vec2) -> Vec2 {
m := vec2_mag(v)
if m == 0 {
return Vec2{0}
}
return v / Vec2{m}
}
vec3_norm0 :: proc(v: Vec3) -> Vec3 {
m := vec3_mag(v)
if m == 0 {
return Vec3{0}
}
return v / Vec3{m}
}
vec4_norm0 :: proc(v: Vec4) -> Vec4 {
m := vec4_mag(v)
if m == 0 {
return Vec4{0}
}
return v / Vec4{m}
}
mat4_identity :: proc() -> Mat4 {
return Mat4{
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
}
}
mat4_transpose :: proc(m: Mat4) -> Mat4 {
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
m[i][j], m[j][i] = m[j][i], m[i][j]
}
}
return m
}
mat4_mul :: proc(a, b: Mat4) -> Mat4 {
c: Mat4
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
c[j][i] = a[0][i]*b[j][0]
+ a[1][i]*b[j][1]
+ a[2][i]*b[j][2]
+ a[3][i]*b[j][3]
}
}
return c
}
mat4_mul_vec4 :: proc(m: Mat4, v: Vec4) -> Vec4 {
return Vec4{
m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z + m[3][0]*v.w,
m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z + m[3][1]*v.w,
m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z + m[3][2]*v.w,
m[0][3]*v.x + m[1][3]*v.y + m[2][3]*v.z + m[3][3]*v.w,
}
}
mat4_inverse :: proc(m: Mat4) -> Mat4 {
o: Mat4
sf00 := m[2][2] * m[3][3] - m[3][2] * m[2][3]
sf01 := m[2][1] * m[3][3] - m[3][1] * m[2][3]
sf02 := m[2][1] * m[3][2] - m[3][1] * m[2][2]
sf03 := m[2][0] * m[3][3] - m[3][0] * m[2][3]
sf04 := m[2][0] * m[3][2] - m[3][0] * m[2][2]
sf05 := m[2][0] * m[3][1] - m[3][0] * m[2][1]
sf06 := m[1][2] * m[3][3] - m[3][2] * m[1][3]
sf07 := m[1][1] * m[3][3] - m[3][1] * m[1][3]
sf08 := m[1][1] * m[3][2] - m[3][1] * m[1][2]
sf09 := m[1][0] * m[3][3] - m[3][0] * m[1][3]
sf10 := m[1][0] * m[3][2] - m[3][0] * m[1][2]
sf11 := m[1][1] * m[3][3] - m[3][1] * m[1][3]
sf12 := m[1][0] * m[3][1] - m[3][0] * m[1][1]
sf13 := m[1][2] * m[2][3] - m[2][2] * m[1][3]
sf14 := m[1][1] * m[2][3] - m[2][1] * m[1][3]
sf15 := m[1][1] * m[2][2] - m[2][1] * m[1][2]
sf16 := m[1][0] * m[2][3] - m[2][0] * m[1][3]
sf17 := m[1][0] * m[2][2] - m[2][0] * m[1][2]
sf18 := m[1][0] * m[2][1] - m[2][0] * m[1][1]
o[0][0] = +(m[1][1] * sf00 - m[1][2] * sf01 + m[1][3] * sf02)
o[0][1] = -(m[1][0] * sf00 - m[1][2] * sf03 + m[1][3] * sf04)
o[0][2] = +(m[1][0] * sf01 - m[1][1] * sf03 + m[1][3] * sf05)
o[0][3] = -(m[1][0] * sf02 - m[1][1] * sf04 + m[1][2] * sf05)
o[1][0] = -(m[0][1] * sf00 - m[0][2] * sf01 + m[0][3] * sf02)
o[1][1] = +(m[0][0] * sf00 - m[0][2] * sf03 + m[0][3] * sf04)
o[1][2] = -(m[0][0] * sf01 - m[0][1] * sf03 + m[0][3] * sf05)
o[1][3] = +(m[0][0] * sf02 - m[0][1] * sf04 + m[0][2] * sf05)
o[2][0] = +(m[0][1] * sf06 - m[0][2] * sf07 + m[0][3] * sf08)
o[2][1] = -(m[0][0] * sf06 - m[0][2] * sf09 + m[0][3] * sf10)
o[2][2] = +(m[0][0] * sf11 - m[0][1] * sf09 + m[0][3] * sf12)
o[2][3] = -(m[0][0] * sf08 - m[0][1] * sf10 + m[0][2] * sf12)
o[3][0] = -(m[0][1] * sf13 - m[0][2] * sf14 + m[0][3] * sf15)
o[3][1] = +(m[0][0] * sf13 - m[0][2] * sf16 + m[0][3] * sf17)
o[3][2] = -(m[0][0] * sf14 - m[0][1] * sf16 + m[0][3] * sf18)
o[3][3] = +(m[0][0] * sf15 - m[0][1] * sf17 + m[0][2] * sf18)
ood := 1.0 / (m[0][0] * o[0][0] +
m[0][1] * o[0][1] +
m[0][2] * o[0][2] +
m[0][3] * o[0][3])
o[0][0] *= ood
o[0][1] *= ood
o[0][2] *= ood
o[0][3] *= ood
o[1][0] *= ood
o[1][1] *= ood
o[1][2] *= ood
o[1][3] *= ood
o[2][0] *= ood
o[2][1] *= ood
o[2][2] *= ood
o[2][3] *= ood
o[3][0] *= ood
o[3][1] *= ood
o[3][2] *= ood
o[3][3] *= ood
return o
}
mat4_translate :: proc(v: Vec3) -> Mat4 {
m := mat4_identity()
m[3][0] = v.x
m[3][1] = v.y
m[3][2] = v.z
m[3][3] = 1
return m
}
mat4_rotate :: proc(v: Vec3, angle_radians: f32) -> Mat4 {
c := cos32(angle_radians)
s := sin32(angle_radians)
a := vec3_norm(v)
t := a * Vec3{1-c}
rot := mat4_identity()
rot[0][0] = c + t.x*a.x
rot[0][1] = 0 + t.x*a.y + s*a.z
rot[0][2] = 0 + t.x*a.z - s*a.y
rot[0][3] = 0
rot[1][0] = 0 + t.y*a.x - s*a.z
rot[1][1] = c + t.y*a.y
rot[1][2] = 0 + t.y*a.z + s*a.x
rot[1][3] = 0
rot[2][0] = 0 + t.z*a.x + s*a.y
rot[2][1] = 0 + t.z*a.y - s*a.x
rot[2][2] = c + t.z*a.z
rot[2][3] = 0
return rot
}
mat4_scale :: proc(m: Mat4, v: Vec3) -> Mat4 {
m[0][0] = v.x
m[1][1] = v.y
m[2][2] = v.z
return m
}
mat4_scalef :: proc(m: Mat4, s: f32) -> Mat4 {
m[0][0] = s
m[1][1] = s
m[2][2] = s
return m
}
mat4_look_at :: proc(eye, centre, up: Vec3) -> Mat4 {
f := vec3_norm(centre - eye)
s := vec3_norm(cross3(f, up))
u := cross3(s, f)
m: Mat4
m[0] = Vec4{+s.x, +s.y, +s.z, 0}
m[1] = Vec4{+u.x, +u.y, +u.z, 0}
m[2] = Vec4{-f.x, -f.y, -f.z, 0}
m[3] = Vec4{dot3(s, eye), dot3(u, eye), dot3(f, eye), 1}
return m
}
mat4_perspective :: proc(fovy, aspect, near, far: f32) -> Mat4 {
m: Mat4
tan_half_fovy := tan32(0.5 * fovy)
m[0][0] = 1.0 / (aspect*tan_half_fovy)
m[1][1] = 1.0 / (tan_half_fovy)
m[2][2] = -(far + near) / (far - near)
m[2][3] = -1.0
m[3][2] = -2.0*far*near / (far - near)
return m
}
mat4_ortho3d :: proc(left, right, bottom, top, near, far: f32) -> Mat4 {
m := mat4_identity()
m[0][0] = +2.0 / (right - left)
m[1][1] = +2.0 / (top - bottom)
m[2][2] = -2.0 / (far - near)
m[3][0] = -(right + left) / (right - left)
m[3][1] = -(top + bottom) / (top - bottom)
m[3][2] = -(far + near) / (far - near)
return m
}
F32_DIG :: 6
F32_EPSILON :: 1.192092896e-07
F32_GUARD :: 0
F32_MANT_DIG :: 24
F32_MAX :: 3.402823466e+38
F32_MAX_10_EXP :: 38
F32_MAX_EXP :: 128
F32_MIN :: 1.175494351e-38
F32_MIN_10_EXP :: -37
F32_MIN_EXP :: -125
F32_NORMALIZE :: 0
F32_RADIX :: 2
F32_ROUNDS :: 1
F64_DIG :: 15 // # of decimal digits of precision
F64_EPSILON :: 2.2204460492503131e-016 // smallest such that 1.0+F64_EPSILON != 1.0
F64_MANT_DIG :: 53 // # of bits in mantissa
F64_MAX :: 1.7976931348623158e+308 // max value
F64_MAX_10_EXP :: 308 // max decimal exponent
F64_MAX_EXP :: 1024 // max binary exponent
F64_MIN :: 2.2250738585072014e-308 // min positive value
F64_MIN_10_EXP :: -307 // min decimal exponent
F64_MIN_EXP :: -1021 // min binary exponent
F64_RADIX :: 2 // exponent radix
F64_ROUNDS :: 1 // addition rounding: near

View File

@@ -1,53 +1,155 @@
#foreign_system_library "opengl32"
ZERO :: 0x0000
ONE :: 0x0001
TRIANGLES :: 0x0004
BLEND :: 0x0be2
SRC_ALPHA :: 0x0302
ONE_MINUS_SRC_ALPHA :: 0x0303
TEXTURE_2D :: 0x0de1
RGBA8 :: 0x8058
UNSIGNED_BYTE :: 0x1401
BGRA_EXT :: 0x80e1
TEXTURE_MAX_LEVEL :: 0x813d
RGBA :: 0x1908
NEAREST :: 0x2600
LINEAR :: 0x2601
DEPTH_BUFFER_BIT :: 0x00000100
STENCIL_BUFFER_BIT :: 0x00000400
COLOR_BUFFER_BIT :: 0x00004000
TEXTURE_MAX_ANISOTROPY_EXT :: 0x84fe
TEXTURE_MAG_FILTER :: 0x2800
TEXTURE_MIN_FILTER :: 0x2801
TEXTURE_WRAP_S :: 0x2802
TEXTURE_WRAP_T :: 0x2803
#import "win32.odin"
#load "opengl_constants.odin"
Clear :: proc(mask: u32) #foreign "glClear"
ClearColor :: proc(r, g, b, a: f32) #foreign "glClearColor"
Begin :: proc(mode: i32) #foreign "glBegin"
End :: proc() #foreign "glEnd"
Color3f :: proc(r, g, b: f32) #foreign "glColor3f"
Color4f :: proc(r, g, b, a: f32) #foreign "glColor4f"
Vertex2f :: proc(x, y: f32) #foreign "glVertex2f"
Vertex3f :: proc(x, y, z: f32) #foreign "glVertex3f"
TexCoord2f :: proc(u, v: f32) #foreign "glTexCoord2f"
LoadIdentity :: proc() #foreign "glLoadIdentity"
Ortho :: proc(left, right, bottom, top, near, far: f64) #foreign "glOrtho"
Finish :: proc() #foreign "glFinish"
BlendFunc :: proc(sfactor, dfactor: i32) #foreign "glBlendFunc"
Enable :: proc(cap: i32) #foreign "glEnable"
Disable :: proc(cap: i32) #foreign "glDisable"
GenTextures :: proc(count: i32, result: ^u32) #foreign "glGenTextures"
DeleteTextures :: proc(count: i32, result: ^u32) #foreign "glDeleteTextures"
TexParameteri :: proc(target, pname, param: i32) #foreign "glTexParameteri"
TexParameterf :: proc(target: i32, pname: i32, param: f32) #foreign "glTexParameterf"
BindTexture :: proc(target: i32, texture: u32) #foreign "glBindTexture"
TexImage2D :: proc(target, level, internal_format, width, height, border, format, _type: i32, pixels: rawptr) #foreign "glTexImage2D"
LoadIdentity :: proc() #foreign "glLoadIdentity"
Viewport :: proc(x, y, width, height: i32) #foreign "glViewport"
Ortho :: proc(left, right, bottom, top, near, far: f64) #foreign "glOrtho"
Color3f :: proc(r, g, b: f32) #foreign "glColor3f"
Vertex3f :: proc(x, y, z: f32) #foreign "glVertex3f"
TexImage2D :: proc(target, level, internal_format,
width, height, border,
format, _type: i32, pixels: rawptr) #foreign "glTexImage2D"
GetError :: proc() -> i32 #foreign "glGetError"
GetString :: proc(name: i32) -> ^byte #foreign "glGetString"
GetIntegerv :: proc(name: i32, v: ^i32) #foreign "glGetIntegerv"
_libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data)
GetProcAddress :: proc(name: string) -> proc() {
assert(name[name.count-1] == 0)
res := win32.wglGetProcAddress(name.data)
if res == nil {
res = win32.GetProcAddress(_libgl, name.data);
}
return res
}
GenBuffers: proc(count: i32, buffers: ^u32)
GenVertexArrays: proc(count: i32, buffers: ^u32)
GenSamplers: proc(count: i32, buffers: ^u32)
BindBuffer: proc(target: i32, buffer: u32)
BindVertexArray: proc(buffer: u32)
BindSampler: proc(position: i32, sampler: u32)
BufferData: proc(target: i32, size: int, data: rawptr, usage: i32)
BufferSubData: proc(target: i32, offset, size: int, data: rawptr)
DrawArrays: proc(mode, first: i32, count: u32)
DrawElements: proc(mode: i32, count: u32, type_: i32, indices: rawptr)
MapBuffer: proc(target, access: i32) -> rawptr
UnmapBuffer: proc(target: i32)
VertexAttribPointer: proc(index: u32, size, type_: i32, normalized: i32, stride: u32, pointer: rawptr)
EnableVertexAttribArray: proc(index: u32)
CreateShader: proc(shader_type: i32) -> u32
ShaderSource: proc(shader: u32, count: u32, string: ^^byte, length: ^i32)
CompileShader: proc(shader: u32)
CreateProgram: proc() -> u32
AttachShader: proc(program, shader: u32)
DetachShader: proc(program, shader: u32)
DeleteShader: proc(shader: u32)
LinkProgram: proc(program: u32)
UseProgram: proc(program: u32)
DeleteProgram: proc(program: u32)
GetShaderiv: proc(shader: u32, pname: i32, params: ^i32)
GetProgramiv: proc(program: u32, pname: i32, params: ^i32)
GetShaderInfoLog: proc(shader: u32, max_length: u32, length: ^u32, info_long: ^byte)
GetProgramInfoLog: proc(program: u32, max_length: u32, length: ^u32, info_long: ^byte)
ActiveTexture: proc(texture: i32)
GenerateMipmap: proc(target: i32)
SamplerParameteri: proc(sampler: u32, pname: i32, param: i32)
SamplerParameterf: proc(sampler: u32, pname: i32, param: f32)
SamplerParameteriv: proc(sampler: u32, pname: i32, params: ^i32)
SamplerParameterfv: proc(sampler: u32, pname: i32, params: ^f32)
SamplerParameterIiv: proc(sampler: u32, pname: i32, params: ^i32)
SamplerParameterIuiv: proc(sampler: u32, pname: i32, params: ^u32)
Uniform1i: proc(loc: i32, v0: i32)
Uniform2i: proc(loc: i32, v0, v1: i32)
Uniform3i: proc(loc: i32, v0, v1, v2: i32)
Uniform4i: proc(loc: i32, v0, v1, v2, v3: i32)
Uniform1f: proc(loc: i32, v0: f32)
Uniform2f: proc(loc: i32, v0, v1: f32)
Uniform3f: proc(loc: i32, v0, v1, v2: f32)
Uniform4f: proc(loc: i32, v0, v1, v2, v3: f32)
UniformMatrix4fv: proc(loc: i32, count: u32, transpose: i32, value: ^f32)
GetUniformLocation: proc(program: u32, name: ^byte) -> i32
init :: proc() {
set_proc_address :: proc(p: rawptr, name: string) #inline { (p as ^proc())^ = GetProcAddress(name) }
set_proc_address(^GenBuffers, "glGenBuffers\x00")
set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00")
set_proc_address(^GenSamplers, "glGenSamplers\x00")
set_proc_address(^BindBuffer, "glBindBuffer\x00")
set_proc_address(^BindSampler, "glBindSampler\x00")
set_proc_address(^BindVertexArray, "glBindVertexArray\x00")
set_proc_address(^BufferData, "glBufferData\x00")
set_proc_address(^BufferSubData, "glBufferSubData\x00")
set_proc_address(^DrawArrays, "glDrawArrays\x00")
set_proc_address(^DrawElements, "glDrawElements\x00")
set_proc_address(^MapBuffer, "glMapBuffer\x00")
set_proc_address(^UnmapBuffer, "glUnmapBuffer\x00")
set_proc_address(^VertexAttribPointer, "glVertexAttribPointer\x00")
set_proc_address(^EnableVertexAttribArray, "glEnableVertexAttribArray\x00")
set_proc_address(^CreateShader, "glCreateShader\x00")
set_proc_address(^ShaderSource, "glShaderSource\x00")
set_proc_address(^CompileShader, "glCompileShader\x00")
set_proc_address(^CreateProgram, "glCreateProgram\x00")
set_proc_address(^AttachShader, "glAttachShader\x00")
set_proc_address(^DetachShader, "glDetachShader\x00")
set_proc_address(^DeleteShader, "glDeleteShader\x00")
set_proc_address(^LinkProgram, "glLinkProgram\x00")
set_proc_address(^UseProgram, "glUseProgram\x00")
set_proc_address(^DeleteProgram, "glDeleteProgram\x00")
set_proc_address(^GetShaderiv, "glGetShaderiv\x00")
set_proc_address(^GetProgramiv, "glGetProgramiv\x00")
set_proc_address(^GetShaderInfoLog, "glGetShaderInfoLog\x00")
set_proc_address(^GetProgramInfoLog, "glGetProgramInfoLog\x00")
set_proc_address(^ActiveTexture, "glActiveTexture\x00")
set_proc_address(^GenerateMipmap, "glGenerateMipmap\x00")
set_proc_address(^Uniform1i, "glUniform1i\x00")
set_proc_address(^UniformMatrix4fv, "glUniformMatrix4fv\x00")
set_proc_address(^GetUniformLocation, "glGetUniformLocation\x00")
set_proc_address(^SamplerParameteri, "glSamplerParameteri\x00")
set_proc_address(^SamplerParameterf, "glSamplerParameterf\x00")
set_proc_address(^SamplerParameteriv, "glSamplerParameteriv\x00")
set_proc_address(^SamplerParameterfv, "glSamplerParameterfv\x00")
set_proc_address(^SamplerParameterIiv, "glSamplerParameterIiv\x00")
set_proc_address(^SamplerParameterIuiv, "glSamplerParameterIuiv\x00")
}

1384
core/opengl_constants.odin Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,23 @@
#import "win32.odin"
#import "fmt.odin"
File :: type struct {
File_Time :: type u64
File :: struct {
Handle :: type win32.HANDLE
handle: Handle
handle: Handle
last_write_time: File_Time
}
open :: proc(name: string) -> (File, bool) {
using win32
buf: [300]byte
copy(buf[:], name as []byte)
f := File{CreateFileA(^buf[0], FILE_GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, nil)}
f := File{
handle = CreateFileA(^buf[0], FILE_GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, nil),
}
success := f.handle != INVALID_HANDLE_VALUE as File.Handle
f.last_write_time = last_write_time(^f)
return f, success
}
@@ -23,6 +29,7 @@ create :: proc(name: string) -> (File, bool) {
handle = CreateFileA(^buf[0], FILE_GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_ALWAYS, 0, nil),
}
success := f.handle != INVALID_HANDLE_VALUE as File.Handle
f.last_write_time = last_write_time(^f)
return f, success
}
@@ -35,19 +42,56 @@ write :: proc(using f: ^File, buf: []byte) -> bool {
return win32.WriteFile(handle, buf.data, buf.count as i32, ^bytes_written, nil) != 0
}
file_has_changed :: proc(f: ^File) -> bool {
last_write_time := last_write_time(f)
if f.last_write_time != last_write_time {
f.last_write_time = last_write_time
return true
}
return false
}
last_write_time :: proc(f: ^File) -> File_Time {
file_info: win32.BY_HANDLE_FILE_INFORMATION
win32.GetFileInformationByHandle(f.handle, ^file_info)
l := file_info.last_write_time.low_date_time as File_Time
h := file_info.last_write_time.high_date_time as File_Time
return l | h << 32
}
last_write_time_by_name :: proc(name: string) -> File_Time {
last_write_time: win32.FILETIME
data: win32.WIN32_FILE_ATTRIBUTE_DATA
buf: [1024]byte
path := buf[:0]
fmt.bprint(^path, name, "\x00")
if win32.GetFileAttributesExA(path.data, win32.GetFileExInfoStandard, ^data) != 0 {
last_write_time = data.last_write_time
}
l := last_write_time.low_date_time as File_Time
h := last_write_time.high_date_time as File_Time
return l | h << 32
}
File_Standard :: type enum {
INPUT,
OUTPUT,
ERROR,
COUNT,
}
// NOTE(bill): Uses startup to initialize it
__std_files := [..]File{
File{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE)},
File{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)},
File{handle = win32.GetStdHandle(win32.STD_ERROR_HANDLE)},
__std_files := [File_Standard.count]File{
{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE)},
{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)},
{handle = win32.GetStdHandle(win32.STD_ERROR_HANDLE)},
}
stdin := ^__std_files[File_Standard.INPUT]

View File

@@ -83,6 +83,35 @@ RECT :: struct #ordered {
bottom: i32
}
FILETIME :: struct #ordered {
low_date_time, high_date_time: u32
}
BY_HANDLE_FILE_INFORMATION :: struct #ordered {
file_attributes: u32
creation_time,
last_access_time,
last_write_time: FILETIME
volume_serial_number,
file_size_high,
file_size_low,
number_of_links,
file_index_high,
file_index_low: u32
}
WIN32_FILE_ATTRIBUTE_DATA :: struct #ordered {
file_attributes: u32
creation_time,
last_access_time,
last_write_time: FILETIME
file_size_high,
file_size_low: u32
}
GET_FILEEX_INFO_LEVELS :: type i32
GetFileExInfoStandard : GET_FILEEX_INFO_LEVELS : 0
GetFileExMaxInfoLevel : GET_FILEEX_INFO_LEVELS : 1
GetLastError :: proc() -> i32 #foreign #dll_import
ExitProcess :: proc(exit_code: u32) #foreign #dll_import
@@ -142,7 +171,9 @@ CreateFileA :: proc(filename: ^u8, desired_access, share_mode: u32,
ReadFile :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign #dll_import
WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> i32 #foreign #dll_import
GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign #dll_import
GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign #dll_import
GetFileAttributesExA :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> BOOL #foreign #dll_import
GetFileInformationByHandle :: proc(file_handle: HANDLE, file_info: ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import
FILE_SHARE_READ :: 0x00000001
FILE_SHARE_WRITE :: 0x00000002
@@ -163,6 +194,9 @@ OPEN_ALWAYS :: 4
TRUNCATE_EXISTING :: 5
HeapAlloc :: proc(h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign #dll_import
HeapReAlloc :: proc(h: HANDLE, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign #dll_import
HeapFree :: proc(h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign #dll_import
@@ -213,6 +247,8 @@ LoadLibraryA :: proc(c_str: ^u8) -> HMODULE #foreign
FreeLibrary :: proc(h: HMODULE) #foreign
GetProcAddress :: proc(h: HMODULE, c_str: ^u8) -> proc() #foreign
GetClientRect :: proc(hwnd: HWND, rect: ^RECT) -> BOOL #foreign
// Windows OpenGL

View File

@@ -11,3 +11,7 @@ Not in any particular order
* Improve SSA design to accommodate for lowering to a "bytecode"
* SSA optimizations
* Parametric Polymorphism
* Documentation Generator for Entities
* Linking Options
- Executable
- Static/Dynamic Library

View File

@@ -92,7 +92,7 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu
if (is_type_maybe(dst)) {
Type *elem = base_type(dst)->Maybe.elem;
return are_types_identical(elem, src);
return are_types_identical(elem, s);
}
if (is_type_untyped_nil(src)) {
@@ -2458,6 +2458,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
GB_ASSERT(entity->type != NULL);
b32 is_not_exported = !is_entity_exported(entity);
// TODO(bill): Fix this for `#import "file.odin" as .`
if (is_not_exported) {
auto found = map_get(&e->ImportName.scope->implicit, hash_string(sel_name));
if (!found && e->ImportName.scope != entity->scope) {

View File

@@ -1722,6 +1722,8 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S
e = ssa_emit_struct_ep(proc, e, index);
} else if (type->kind == Type_Vector) {
e = ssa_emit_array_ep(proc, e, index);
} else if (type->kind == Type_Array) {
e = ssa_emit_array_ep(proc, e, index);
} else {
GB_PANIC("un-gep-able type");
}
@@ -5098,6 +5100,9 @@ void ssa_gen_tree(ssaGen *s) {
ssaValue *count = ssa_emit_struct_ep(proc, tag, 2);
ssa_emit_store(proc, count, ssa_make_const_int(a, t->Vector.count));
ssaValue *align = ssa_emit_struct_ep(proc, tag, 3);
ssa_emit_store(proc, count, ssa_make_const_int(a, type_align_of(m->sizes, a, t)));
} break;
case Type_Record: {
switch (t->Record.kind) {
@@ -5245,8 +5250,8 @@ void ssa_gen_tree(ssaGen *s) {
}
for (isize i = 0; i < count; i++) {
ssaValue *value_gep = ssa_emit_struct_ep(proc, value_array, i);
ssaValue *name_gep = ssa_emit_struct_ep(proc, name_array, i);
ssaValue *value_gep = ssa_emit_array_ep(proc, value_array, i);
ssaValue *name_gep = ssa_emit_array_ep(proc, name_array, i);
ssa_emit_store(proc, value_gep, ssa_make_const_i64(a, fields[i]->Constant.value.value_integer));
ssa_emit_store(proc, name_gep, ssa_make_const_string(a, fields[i]->token.string));

View File

@@ -37,6 +37,9 @@ TOKEN_KIND(Token__OperatorBegin, "_OperatorBegin"), \
\
TOKEN_KIND(Token_Prime, "'"), \
TOKEN_KIND(Token_DoublePrime, "''"), \
\
TOKEN_KIND(Token_CmpAnd, "&&"), \
TOKEN_KIND(Token_CmpOr, "||"), \
\
TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \
TOKEN_KIND(Token_AddEq, "+="), \
@@ -50,16 +53,13 @@ TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \
TOKEN_KIND(Token_AndNotEq, "&~="), \
TOKEN_KIND(Token_ShlEq, "<<="), \
TOKEN_KIND(Token_ShrEq, ">>="), \
TOKEN_KIND(Token_CmpAndEq, "&&="), \
TOKEN_KIND(Token_CmpOrEq, "||="), \
TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \
TOKEN_KIND(Token_Increment, "++"), \
TOKEN_KIND(Token_Decrement, "--"), \
TOKEN_KIND(Token_ArrowRight, "->"), \
TOKEN_KIND(Token_ArrowLeft, "<-"), \
\
TOKEN_KIND(Token_CmpAnd, "&&"), \
TOKEN_KIND(Token_CmpOr, "||"), \
TOKEN_KIND(Token_CmpAndEq, "&&="), \
TOKEN_KIND(Token_CmpOrEq, "||="), \
\
TOKEN_KIND(Token__ComparisonBegin, "_ComparisonBegin"), \
TOKEN_KIND(Token_CmpEq, "=="), \

20
todo.md
View File

@@ -1,16 +1,5 @@
# Todo
## Tokenizer
* Unicode character category check - Letters, Digits
* Extra operators
- << and <<=
- >> and >>=
## Parser
* Extra checking here rather than in the checker
* Mulitple files (done)
- Namespaces
## Checker
* Cyclic Type Checking
- type A: struct { b: B; }; type B: struct { a: A; };
@@ -19,20 +8,11 @@
- integer
- rational
- real
* Multiple files (done)
- Namespaces
## Codegen
* Emit LLVM-IR using custom library
* Debug info
## Command Line Tool
* Begin!!!
* Choose/determine architecture
## Language
* should `if/for` statements init statement be of the same scope as the block scope or not? (currently not)