mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 20:40:28 +00:00
Semicolons are required; when condition for certain file scope declarations; #import syntax change
This commit is contained in:
@@ -1,34 +1,6 @@
|
||||
#import "fmt.odin"
|
||||
#import "utf8.odin"
|
||||
#import "fmt.odin";
|
||||
|
||||
main :: proc() {
|
||||
MAX :: 64
|
||||
buf: [MAX]rune
|
||||
backing: [MAX]byte
|
||||
offset: int
|
||||
|
||||
msg := "Hello"
|
||||
|
||||
count := utf8.rune_count(msg)
|
||||
assert(count <= MAX)
|
||||
runes := buf[:count]
|
||||
|
||||
offset = 0
|
||||
for i := 0; i < count; i++ {
|
||||
s := msg[offset:]
|
||||
r, len := utf8.decode_rune(s)
|
||||
runes[count-i-1] = r
|
||||
offset += len
|
||||
}
|
||||
|
||||
offset = 0
|
||||
for i := 0; i < count; i++ {
|
||||
data, len := utf8.encode_rune(runes[i])
|
||||
copy(backing[offset:], data[:len])
|
||||
offset += len
|
||||
}
|
||||
|
||||
reverse := backing[:offset] as string
|
||||
fmt.println(reverse) // olleH
|
||||
fmt.println("Hellope");
|
||||
}
|
||||
|
||||
|
||||
188
code/game.odin
188
code/game.odin
@@ -1,60 +1,60 @@
|
||||
#import "win32.odin"
|
||||
#import "fmt.odin"
|
||||
#import "math.odin"
|
||||
#import "os.odin"
|
||||
#import "opengl.odin" as gl
|
||||
#import "win32.odin" when ODIN_OS == "windows";
|
||||
#import "fmt.odin";
|
||||
#import "math.odin";
|
||||
#import "os.odin";
|
||||
#import gl "opengl.odin";
|
||||
|
||||
TWO_HEARTS :: '💕'
|
||||
TWO_HEARTS :: '💕';
|
||||
|
||||
win32_perf_count_freq := win32.GetQueryPerformanceFrequency()
|
||||
win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
|
||||
time_now :: proc() -> f64 {
|
||||
assert(win32_perf_count_freq != 0)
|
||||
assert(win32_perf_count_freq != 0);
|
||||
|
||||
counter: i64
|
||||
win32.QueryPerformanceCounter(^counter)
|
||||
result := counter as f64 / win32_perf_count_freq as f64
|
||||
return result
|
||||
counter: i64;
|
||||
win32.QueryPerformanceCounter(^counter);
|
||||
result := counter as f64 / win32_perf_count_freq as f64;
|
||||
return result;
|
||||
}
|
||||
win32_print_last_error :: proc() {
|
||||
err_code := win32.GetLastError() as int
|
||||
err_code := win32.GetLastError() as int;
|
||||
if err_code != 0 {
|
||||
fmt.println("GetLastError: %", err_code)
|
||||
fmt.println("GetLastError: %", err_code);
|
||||
}
|
||||
}
|
||||
|
||||
// Yuk!
|
||||
to_c_string :: proc(s: string) -> []u8 {
|
||||
c_str := new_slice(u8, s.count+1)
|
||||
copy(c_str, s as []byte)
|
||||
c_str[s.count] = 0
|
||||
return c_str
|
||||
c_str := new_slice(u8, s.count+1);
|
||||
copy(c_str, s as []byte);
|
||||
c_str[s.count] = 0;
|
||||
return c_str;
|
||||
}
|
||||
|
||||
|
||||
Window :: struct {
|
||||
width, height: int
|
||||
wc: win32.WNDCLASSEXA
|
||||
dc: win32.HDC
|
||||
hwnd: win32.HWND
|
||||
opengl_context, rc: win32.HGLRC
|
||||
c_title: []u8
|
||||
width, height: int;
|
||||
wc: win32.WNDCLASSEXA;
|
||||
dc: win32.HDC;
|
||||
hwnd: win32.HWND;
|
||||
opengl_context, rc: win32.HGLRC;
|
||||
c_title: []u8;
|
||||
}
|
||||
|
||||
make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC) -> (Window, bool) {
|
||||
using win32
|
||||
using win32;
|
||||
|
||||
w: Window
|
||||
w.width, w.height = msg, height
|
||||
w: Window;
|
||||
w.width, w.height = msg, height;
|
||||
|
||||
class_name := "Win32-Odin-Window\x00"
|
||||
c_class_name := class_name.data
|
||||
class_name := "Win32-Odin-Window\x00";
|
||||
c_class_name := class_name.data;
|
||||
if title[title.count-1] != 0 {
|
||||
w.c_title = to_c_string(title)
|
||||
w.c_title = to_c_string(title);
|
||||
} else {
|
||||
w.c_title = title as []u8
|
||||
w.c_title = title as []u8;
|
||||
}
|
||||
|
||||
instance := GetModuleHandleA(nil)
|
||||
instance := GetModuleHandleA(nil);
|
||||
|
||||
w.wc = WNDCLASSEXA{
|
||||
size = size_of(WNDCLASSEXA) as u32,
|
||||
@@ -65,8 +65,8 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
|
||||
};
|
||||
|
||||
if RegisterClassExA(^w.wc) == 0 {
|
||||
win32_print_last_error()
|
||||
return w, false
|
||||
win32_print_last_error();
|
||||
return w, false;
|
||||
}
|
||||
|
||||
w.hwnd = CreateWindowExA(0,
|
||||
@@ -74,14 +74,14 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
|
||||
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
w.width as i32, w.height as i32,
|
||||
nil, nil, instance, nil)
|
||||
nil, nil, instance, nil);
|
||||
|
||||
if w.hwnd == nil {
|
||||
win32_print_last_error()
|
||||
return w, false
|
||||
win32_print_last_error();
|
||||
return w, false;
|
||||
}
|
||||
|
||||
w.dc = GetDC(w.hwnd)
|
||||
w.dc = GetDC(w.hwnd);
|
||||
|
||||
{
|
||||
pfd := PIXELFORMATDESCRIPTOR{
|
||||
@@ -94,122 +94,122 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
|
||||
depth_bits = 24,
|
||||
stencil_bits = 8,
|
||||
layer_type = PFD_MAIN_PLANE,
|
||||
}
|
||||
};
|
||||
|
||||
SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil)
|
||||
w.opengl_context = wglCreateContext(w.dc)
|
||||
wglMakeCurrent(w.dc, w.opengl_context)
|
||||
SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil);
|
||||
w.opengl_context = wglCreateContext(w.dc);
|
||||
wglMakeCurrent(w.dc, w.opengl_context);
|
||||
|
||||
attribs := [8]i32{
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 2,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||
0, // NOTE(bill): tells the proc that this is the end of attribs
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
return w, true
|
||||
return w, true;
|
||||
}
|
||||
|
||||
destroy_window :: proc(w: ^Window) {
|
||||
free(w.c_title.data)
|
||||
free(w.c_title.data);
|
||||
}
|
||||
|
||||
display_window :: proc(w: ^Window) {
|
||||
win32.SwapBuffers(w.dc)
|
||||
win32.SwapBuffers(w.dc);
|
||||
}
|
||||
|
||||
|
||||
run :: proc() {
|
||||
using win32
|
||||
using math
|
||||
using win32;
|
||||
using math;
|
||||
|
||||
win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline {
|
||||
if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT {
|
||||
os.exit(0)
|
||||
return 0
|
||||
os.exit(0);
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam)
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
window, window_success := make_window("Odin Language Demo", 854, 480, win32_proc)
|
||||
window, window_success := make_window("Odin Language Demo", 854, 480, win32_proc);
|
||||
if !window_success {
|
||||
return
|
||||
return;
|
||||
}
|
||||
defer destroy_window(^window)
|
||||
defer destroy_window(^window);
|
||||
|
||||
gl.init()
|
||||
gl.init();
|
||||
|
||||
|
||||
prev_time := time_now()
|
||||
running := true
|
||||
prev_time := time_now();
|
||||
running := true;
|
||||
|
||||
pos := Vec2{100, 100}
|
||||
pos := Vec2{100, 100};
|
||||
|
||||
for running {
|
||||
curr_time := time_now()
|
||||
dt := (curr_time - prev_time) as f32
|
||||
prev_time = curr_time
|
||||
curr_time := time_now();
|
||||
dt := (curr_time - prev_time) as f32;
|
||||
prev_time = curr_time;
|
||||
|
||||
msg: MSG
|
||||
msg: MSG;
|
||||
for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 {
|
||||
if msg.message == WM_QUIT {
|
||||
running = false
|
||||
running = false;
|
||||
}
|
||||
TranslateMessage(^msg)
|
||||
DispatchMessageA(^msg)
|
||||
TranslateMessage(^msg);
|
||||
DispatchMessageA(^msg);
|
||||
}
|
||||
|
||||
if is_key_down(Key_Code.ESCAPE) {
|
||||
running = false
|
||||
running = false;
|
||||
}
|
||||
|
||||
{
|
||||
SPEED :: 500
|
||||
v: Vec2
|
||||
SPEED :: 500;
|
||||
v: Vec2;
|
||||
|
||||
if is_key_down(Key_Code.RIGHT) { v[0] += 1 }
|
||||
if is_key_down(Key_Code.LEFT) { v[0] -= 1 }
|
||||
if is_key_down(Key_Code.UP) { v[1] += 1 }
|
||||
if is_key_down(Key_Code.DOWN) { v[1] -= 1 }
|
||||
if is_key_down(Key_Code.RIGHT) { v[0] += 1; }
|
||||
if is_key_down(Key_Code.LEFT) { v[0] -= 1; }
|
||||
if is_key_down(Key_Code.UP) { v[1] += 1; }
|
||||
if is_key_down(Key_Code.DOWN) { v[1] -= 1; }
|
||||
|
||||
v = vec2_norm0(v)
|
||||
v = vec2_norm0(v);
|
||||
|
||||
pos += v * Vec2{SPEED * dt}
|
||||
pos += v * Vec2{SPEED * dt};
|
||||
}
|
||||
|
||||
|
||||
gl.ClearColor(0.5, 0.7, 1.0, 1.0)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
gl.ClearColor(0.5, 0.7, 1.0, 1.0);
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
gl.LoadIdentity()
|
||||
gl.LoadIdentity();
|
||||
gl.Ortho(0, window.width as f64,
|
||||
0, window.height as f64, 0, 1)
|
||||
0, window.height as f64, 0, 1);
|
||||
|
||||
draw_rect :: proc(x, y, w, h: f32) {
|
||||
gl.Begin(gl.TRIANGLES)
|
||||
defer gl.End()
|
||||
gl.Begin(gl.TRIANGLES);
|
||||
defer gl.End();
|
||||
|
||||
gl.Color3f(1, 0, 0); gl.Vertex3f(x, y, 0)
|
||||
gl.Color3f(0, 1, 0); gl.Vertex3f(x+w, y, 0)
|
||||
gl.Color3f(0, 0, 1); gl.Vertex3f(x+w, y+h, 0)
|
||||
gl.Color3f(1, 0, 0); gl.Vertex3f(x, y, 0);
|
||||
gl.Color3f(0, 1, 0); gl.Vertex3f(x+w, y, 0);
|
||||
gl.Color3f(0, 0, 1); gl.Vertex3f(x+w, y+h, 0);
|
||||
|
||||
gl.Color3f(0, 0, 1); gl.Vertex3f(x+w, y+h, 0)
|
||||
gl.Color3f(1, 1, 0); gl.Vertex3f(x, y+h, 0)
|
||||
gl.Color3f(1, 0, 0); gl.Vertex3f(x, y, 0)
|
||||
gl.Color3f(0, 0, 1); gl.Vertex3f(x+w, y+h, 0);
|
||||
gl.Color3f(1, 1, 0); gl.Vertex3f(x, y+h, 0);
|
||||
gl.Color3f(1, 0, 0); gl.Vertex3f(x, y, 0);
|
||||
}
|
||||
|
||||
draw_rect(pos.x, pos.y, 50, 50)
|
||||
draw_rect(pos.x, pos.y, 50, 50);
|
||||
|
||||
display_window(^window)
|
||||
ms_to_sleep := (16 - 1000*dt) as i32
|
||||
display_window(^window);
|
||||
ms_to_sleep := (16 - 1000*dt) as i32;
|
||||
if ms_to_sleep > 0 {
|
||||
win32.Sleep(ms_to_sleep)
|
||||
win32.Sleep(ms_to_sleep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#import "fmt.odin" as fmt
|
||||
#import "fmt.odin";
|
||||
|
||||
#foreign_system_library "Ws2_32"
|
||||
#foreign_system_library "Ws2_32" when ODIN_OS == "windows";
|
||||
|
||||
|
||||
SOCKET :: type uint
|
||||
INVALID_SOCKET :: ~(0 as SOCKET)
|
||||
SOCKET :: type uint;
|
||||
INVALID_SOCKET :: ~(0 as SOCKET);
|
||||
|
||||
AF :: enum i32 {
|
||||
UNSPEC = 0, // unspecified
|
||||
@@ -37,45 +37,45 @@ AF :: enum i32 {
|
||||
MAX = 26,
|
||||
}
|
||||
|
||||
SOCK_STREAM :: 1
|
||||
SOCKET_ERROR :: -1
|
||||
IPPROTO_TCP :: 6
|
||||
AI_PASSIVE :: 0x0020
|
||||
SOMAXCONN :: 128
|
||||
SOCK_STREAM :: 1;
|
||||
SOCKET_ERROR :: -1;
|
||||
IPPROTO_TCP :: 6;
|
||||
AI_PASSIVE :: 0x0020;
|
||||
SOMAXCONN :: 128;
|
||||
|
||||
SD_RECEIVE :: 0
|
||||
SD_SEND :: 1
|
||||
SD_BOTH :: 2
|
||||
SD_RECEIVE :: 0;
|
||||
SD_SEND :: 1;
|
||||
SD_BOTH :: 2;
|
||||
|
||||
WSADESCRIPTION_LEN :: 256
|
||||
WSASYS_STATUS_LEN :: 128
|
||||
WSADESCRIPTION_LEN :: 256;
|
||||
WSASYS_STATUS_LEN :: 128;
|
||||
WSADATA :: struct #ordered {
|
||||
version: i16
|
||||
high_version: i16
|
||||
version: i16;
|
||||
high_version: i16;
|
||||
|
||||
|
||||
// NOTE(bill): This is x64 ordering
|
||||
max_sockets: u16
|
||||
max_udp_dg: u16
|
||||
vendor_info: ^byte
|
||||
description: [WSADESCRIPTION_LEN+1]byte
|
||||
system_status: [WSASYS_STATUS_LEN+1]byte
|
||||
max_sockets: u16;
|
||||
max_udp_dg: u16;
|
||||
vendor_info: ^byte;
|
||||
description: [WSADESCRIPTION_LEN+1]byte;
|
||||
system_status: [WSASYS_STATUS_LEN+1]byte;
|
||||
}
|
||||
|
||||
addrinfo :: struct #ordered {
|
||||
flags: i32
|
||||
family: i32
|
||||
socktype: i32
|
||||
protocol: i32
|
||||
addrlen: uint
|
||||
canonname: ^u8
|
||||
addr: ^sockaddr
|
||||
next: ^addrinfo
|
||||
flags: i32;
|
||||
family: i32;
|
||||
socktype: i32;
|
||||
protocol: i32;
|
||||
addrlen: uint;
|
||||
canonname: ^u8;
|
||||
addr: ^sockaddr;
|
||||
next: ^addrinfo;
|
||||
}
|
||||
|
||||
sockaddr :: struct #ordered {
|
||||
family: u16
|
||||
data: [14]byte
|
||||
family: u16;
|
||||
data: [14]byte;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,52 +94,52 @@ shutdown :: proc(s: SOCKET, how: i32) -> i32
|
||||
WSAGetLastError :: proc() -> i32 #foreign #dll_import
|
||||
|
||||
to_c_string :: proc(s: string) -> ^byte {
|
||||
c_str := new_slice(byte, s.count+1)
|
||||
assert(c_str.data != null)
|
||||
copy(c_str, s as []byte)
|
||||
c_str[s.count] = 0
|
||||
return c_str.data
|
||||
c_str := new_slice(byte, s.count+1);
|
||||
assert(c_str.data != nil);
|
||||
copy(c_str, s as []byte);
|
||||
c_str[s.count] = 0;
|
||||
return c_str.data;
|
||||
}
|
||||
|
||||
run :: proc() {
|
||||
wsa: WSADATA
|
||||
res: ^addrinfo = null
|
||||
hints: addrinfo
|
||||
s, client: SOCKET
|
||||
wsa: WSADATA;
|
||||
res: ^addrinfo = nil;
|
||||
hints: addrinfo;
|
||||
s, client: SOCKET;
|
||||
|
||||
if WSAStartup(2 | (2 << 8), ^wsa) != 0 {
|
||||
fmt.println("WSAStartup failed: ", WSAGetLastError())
|
||||
return
|
||||
fmt.println("WSAStartup failed: ", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
defer WSACleanup()
|
||||
defer WSACleanup();
|
||||
|
||||
hints.family = AF.INET as i32
|
||||
hints.socktype = SOCK_STREAM
|
||||
hints.protocol = IPPROTO_TCP
|
||||
hints.flags = AI_PASSIVE
|
||||
hints.family = AF.INET as i32;
|
||||
hints.socktype = SOCK_STREAM;
|
||||
hints.protocol = IPPROTO_TCP;
|
||||
hints.flags = AI_PASSIVE;
|
||||
|
||||
if getaddrinfo(null, to_c_string("8080"), ^hints, ^res) != 0 {
|
||||
fmt.println("getaddrinfo failed: ", WSAGetLastError())
|
||||
return
|
||||
if getaddrinfo(nil, to_c_string("8080"), ^hints, ^res) != 0 {
|
||||
fmt.println("getaddrinfo failed: ", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
defer freeaddrinfo(res)
|
||||
defer freeaddrinfo(res);
|
||||
|
||||
s = socket(res.family, res.socktype, res.protocol)
|
||||
s = socket(res.family, res.socktype, res.protocol);
|
||||
if s == INVALID_SOCKET {
|
||||
fmt.println("socket failed: ", WSAGetLastError())
|
||||
return
|
||||
fmt.println("socket failed: ", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
defer closesocket(s)
|
||||
defer closesocket(s);
|
||||
|
||||
bind(s, res.addr, res.addrlen as i32)
|
||||
listen(s, SOMAXCONN)
|
||||
bind(s, res.addr, res.addrlen as i32);
|
||||
listen(s, SOMAXCONN);
|
||||
|
||||
client = accept(s, null, null)
|
||||
client = accept(s, nil, 0);
|
||||
if client == INVALID_SOCKET {
|
||||
fmt.println("socket failed: ", WSAGetLastError())
|
||||
return
|
||||
fmt.println("socket failed: ", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
defer closesocket(client)
|
||||
defer closesocket(client);
|
||||
|
||||
html :=
|
||||
`HTTP/1.1 200 OK
|
||||
@@ -154,27 +154,27 @@ Content-type: text/html
|
||||
<h1 style="color: orange;">Odin Server Demo</h1>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
`;
|
||||
|
||||
buf: [1024]byte
|
||||
buf: [1024]byte;
|
||||
for {
|
||||
bytes := recv(client, ^buf[0], buf.count as i32, 0)
|
||||
bytes := recv(client, ^buf[0], buf.count as i32, 0);
|
||||
if bytes > 0 {
|
||||
// fmt.println(buf[:bytes] as string)
|
||||
bytes_sent := send(client, html.data, (html.count-1) as i32, 0)
|
||||
// fmt.println(buf[:bytes] as string);
|
||||
bytes_sent := send(client, html.data, (html.count-1) as i32, 0);
|
||||
if bytes_sent == SOCKET_ERROR {
|
||||
fmt.println("send failed: ", WSAGetLastError())
|
||||
return
|
||||
fmt.println("send failed: ", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
break
|
||||
break;
|
||||
} else if bytes == 0 {
|
||||
fmt.println("Connection closing...")
|
||||
break
|
||||
fmt.println("Connection closing...");
|
||||
break;
|
||||
} else {
|
||||
fmt.println("recv failed: ", WSAGetLastError())
|
||||
return
|
||||
fmt.println("recv failed: ", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
shutdown(client, SD_SEND)
|
||||
shutdown(client, SD_SEND);
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ namespaces_and_files :: proc() {
|
||||
#import "file.odin" as _
|
||||
|
||||
// Exporting import
|
||||
#load "file.odin"
|
||||
#include "file.odin"
|
||||
*/
|
||||
|
||||
// Talk about scope rules and diagram
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Demo 002
|
||||
#load "basic.odin"
|
||||
#load "math.odin"
|
||||
// #load "game.odin"
|
||||
#include "basic.odin"
|
||||
#include "math.odin"
|
||||
// #include "game.odin"
|
||||
|
||||
#thread_local tls_int: int
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#load "win32.odin"
|
||||
#include "win32.odin"
|
||||
|
||||
assume :: proc(cond: bool) #foreign "llvm.assume"
|
||||
|
||||
|
||||
278
code/punity.odin
278
code/punity.odin
@@ -1,34 +1,34 @@
|
||||
#import "win32.odin"
|
||||
#import "fmt.odin"
|
||||
#import "os.odin"
|
||||
#import "win32.odin";
|
||||
#import "fmt.odin";
|
||||
#import "os.odin";
|
||||
|
||||
CANVAS_WIDTH :: 128
|
||||
CANVAS_HEIGHT :: 128
|
||||
CANVAS_SCALE :: 3
|
||||
FRAME_TIME :: 1.0/30.0
|
||||
WINDOW_TITLE : string : "Punity\x00"
|
||||
CANVAS_WIDTH :: 128;
|
||||
CANVAS_HEIGHT :: 128;
|
||||
CANVAS_SCALE :: 3;
|
||||
FRAME_TIME :: 1.0/30.0;
|
||||
WINDOW_TITLE :: "Punity\x00";
|
||||
|
||||
_ := compile_assert(CANVAS_WIDTH % 16 == 0)
|
||||
_ := compile_assert(CANVAS_WIDTH % 16 == 0);
|
||||
|
||||
WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE
|
||||
WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE
|
||||
WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE;
|
||||
WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE;
|
||||
|
||||
|
||||
STACK_CAPACITY :: 1<<20
|
||||
STORAGE_CAPACITY :: 1<<20
|
||||
STACK_CAPACITY :: 1<<20;
|
||||
STORAGE_CAPACITY :: 1<<20;
|
||||
|
||||
DRAW_LIST_RESERVE :: 128
|
||||
DRAW_LIST_RESERVE :: 128;
|
||||
|
||||
MAX_KEYS :: 256
|
||||
MAX_KEYS :: 256;
|
||||
|
||||
Core :: struct {
|
||||
stack: ^Bank
|
||||
storage: ^Bank
|
||||
stack: ^Bank;
|
||||
storage: ^Bank;
|
||||
|
||||
running: bool
|
||||
key_modifiers: u32
|
||||
key_states: [MAX_KEYS]byte
|
||||
key_deltas: [MAX_KEYS]byte
|
||||
running: bool;
|
||||
key_modifiers: u32;
|
||||
key_states: [MAX_KEYS]byte;
|
||||
key_deltas: [MAX_KEYS]byte;
|
||||
|
||||
perf_frame,
|
||||
perf_frame_inner,
|
||||
@@ -36,70 +36,70 @@ Core :: struct {
|
||||
perf_audio,
|
||||
perf_blit,
|
||||
perf_blit_cvt,
|
||||
perf_blit_gdi: Perf_Span
|
||||
perf_blit_gdi: Perf_Span;
|
||||
|
||||
frame: i64
|
||||
frame: i64;
|
||||
|
||||
canvas: Canvas
|
||||
draw_list: ^Draw_List
|
||||
canvas: Canvas;
|
||||
draw_list: ^Draw_List;
|
||||
}
|
||||
|
||||
Perf_Span :: struct {
|
||||
stamp: f64
|
||||
delta: f32
|
||||
stamp: f64;
|
||||
delta: f32;
|
||||
}
|
||||
|
||||
Bank :: struct {
|
||||
memory: []byte
|
||||
cursor: int
|
||||
memory: []byte;
|
||||
cursor: int;
|
||||
}
|
||||
|
||||
Bank_State :: struct {
|
||||
state: Bank
|
||||
bank: ^Bank
|
||||
state: Bank;
|
||||
bank: ^Bank;
|
||||
}
|
||||
|
||||
|
||||
Color :: raw_union {
|
||||
using channels: struct{ a, b, g, r: byte }
|
||||
rgba: u32
|
||||
using channels: struct{ a, b, g, r: byte; };
|
||||
rgba: u32;
|
||||
}
|
||||
|
||||
Palette :: struct {
|
||||
colors: [256]Color
|
||||
colors_count: byte
|
||||
colors: [256]Color;
|
||||
colors_count: byte;
|
||||
}
|
||||
|
||||
|
||||
Rect :: raw_union {
|
||||
using minmax: struct {
|
||||
min_x, min_y, max_x, max_y: int
|
||||
}
|
||||
min_x, min_y, max_x, max_y: int;
|
||||
};
|
||||
using pos: struct {
|
||||
left, top, right, bottom: int
|
||||
}
|
||||
e: [4]int
|
||||
left, top, right, bottom: int;
|
||||
};
|
||||
e: [4]int;
|
||||
}
|
||||
|
||||
Bitmap :: struct {
|
||||
pixels: []byte
|
||||
width: int
|
||||
height: int
|
||||
pixels: []byte;
|
||||
width: int;
|
||||
height: int;
|
||||
}
|
||||
|
||||
Font :: struct {
|
||||
using bitmap: Bitmap
|
||||
char_width: int
|
||||
char_height: int
|
||||
using bitmap: Bitmap;
|
||||
char_width: int;
|
||||
char_height: int;
|
||||
}
|
||||
|
||||
Canvas :: struct {
|
||||
using bitmap: ^Bitmap
|
||||
palette: Palette
|
||||
translate_x: int
|
||||
translate_y: int
|
||||
clip: Rect
|
||||
font: ^Font
|
||||
using bitmap: ^Bitmap;
|
||||
palette: Palette;
|
||||
translate_x: int;
|
||||
translate_y: int;
|
||||
clip: Rect;
|
||||
font: ^Font;
|
||||
}
|
||||
|
||||
DrawFlag :: enum {
|
||||
@@ -114,7 +114,7 @@ Draw_List :: struct {
|
||||
Item :: struct {
|
||||
|
||||
}
|
||||
items: []Item
|
||||
items: []Item;
|
||||
}
|
||||
|
||||
Key :: enum {
|
||||
@@ -272,37 +272,36 @@ Key :: enum {
|
||||
|
||||
|
||||
key_down :: proc(k: Key) -> bool {
|
||||
return _core.key_states[k] != 0
|
||||
return _core.key_states[k] != 0;
|
||||
}
|
||||
|
||||
key_pressed :: proc(k: Key) -> bool {
|
||||
return (_core.key_deltas[k] != 0) && key_down(k)
|
||||
return (_core.key_deltas[k] != 0) && key_down(k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
win32_perf_count_freq := win32.GetQueryPerformanceFrequency()
|
||||
win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
|
||||
time_now :: proc() -> f64 {
|
||||
assert(win32_perf_count_freq != 0)
|
||||
assert(win32_perf_count_freq != 0);
|
||||
|
||||
counter: i64
|
||||
win32.QueryPerformanceCounter(^counter)
|
||||
result := counter as f64 / win32_perf_count_freq as f64
|
||||
return result
|
||||
counter: i64;
|
||||
win32.QueryPerformanceCounter(^counter);
|
||||
result := counter as f64 / win32_perf_count_freq as f64;
|
||||
return result;
|
||||
}
|
||||
|
||||
_core: Core
|
||||
_core: Core;
|
||||
|
||||
run :: proc(user_init, user_step: proc(c: ^Core)) {
|
||||
using win32
|
||||
using win32;
|
||||
|
||||
|
||||
_core.running = true
|
||||
_core.running = true;
|
||||
|
||||
win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline #stdcall {
|
||||
win32_app_key_mods :: proc() -> u32 {
|
||||
mods: u32 = 0
|
||||
mods: u32 = 0;
|
||||
|
||||
if is_key_down(Key_Code.SHIFT) {
|
||||
mods |= Key.MOD_SHIFT as u32;
|
||||
@@ -317,33 +316,33 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
||||
mods |= Key.MOD_SUPER as u32;
|
||||
}
|
||||
|
||||
return mods
|
||||
return mods;
|
||||
}
|
||||
|
||||
match msg {
|
||||
case WM_KEYDOWN:
|
||||
_core.key_modifiers = win32_app_key_mods()
|
||||
_core.key_modifiers = win32_app_key_mods();
|
||||
if wparam < MAX_KEYS {
|
||||
_core.key_states[wparam] = 1
|
||||
_core.key_deltas[wparam] = 1
|
||||
_core.key_states[wparam] = 1;
|
||||
_core.key_deltas[wparam] = 1;
|
||||
}
|
||||
return 0
|
||||
return 0;
|
||||
|
||||
case WM_KEYUP:
|
||||
_core.key_modifiers = win32_app_key_mods()
|
||||
_core.key_modifiers = win32_app_key_mods();
|
||||
if wparam < MAX_KEYS {
|
||||
_core.key_states[wparam] = 0
|
||||
_core.key_deltas[wparam] = 1
|
||||
_core.key_states[wparam] = 0;
|
||||
_core.key_deltas[wparam] = 1;
|
||||
}
|
||||
return 0
|
||||
return 0;
|
||||
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0)
|
||||
_core.running = false
|
||||
return 0
|
||||
PostQuitMessage(0);
|
||||
_core.running = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam)
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
@@ -351,30 +350,30 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
||||
class_name = ("Punity\x00" as string).data, // C-style string
|
||||
size = size_of(WNDCLASSEXA) as u32,
|
||||
style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||
instance = GetModuleHandleA(null) as HINSTANCE,
|
||||
instance = GetModuleHandleA(nil) as HINSTANCE,
|
||||
wnd_proc = win32_proc,
|
||||
// wnd_proc = DefWindowProcA,
|
||||
background = GetStockObject(BLACK_BRUSH) as HBRUSH,
|
||||
}
|
||||
};
|
||||
|
||||
if RegisterClassExA(^window_class) == 0 {
|
||||
fmt.fprintln(os.stderr, "RegisterClassExA failed")
|
||||
return
|
||||
fmt.fprintln(os.stderr, "RegisterClassExA failed");
|
||||
return;
|
||||
}
|
||||
|
||||
screen_width := GetSystemMetrics(SM_CXSCREEN)
|
||||
screen_height := GetSystemMetrics(SM_CYSCREEN)
|
||||
screen_width := GetSystemMetrics(SM_CXSCREEN);
|
||||
screen_height := GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
rc: RECT
|
||||
rc.left = (screen_width - WINDOW_WIDTH) / 2
|
||||
rc.top = (screen_height - WINDOW_HEIGHT) / 2
|
||||
rc.right = rc.left + WINDOW_WIDTH
|
||||
rc.bottom = rc.top + WINDOW_HEIGHT
|
||||
rc: RECT;
|
||||
rc.left = (screen_width - WINDOW_WIDTH) / 2;
|
||||
rc.top = (screen_height - WINDOW_HEIGHT) / 2;
|
||||
rc.right = rc.left + WINDOW_WIDTH;
|
||||
rc.bottom = rc.top + WINDOW_HEIGHT;
|
||||
|
||||
style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
|
||||
assert(AdjustWindowRect(^rc, style, 0) != 0)
|
||||
style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||
assert(AdjustWindowRect(^rc, style, 0) != 0);
|
||||
|
||||
wt := WINDOW_TITLE
|
||||
wt := WINDOW_TITLE;
|
||||
|
||||
win32_window := CreateWindowExA(0,
|
||||
window_class.class_name,
|
||||
@@ -382,83 +381,82 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
||||
style,
|
||||
rc.left, rc.top,
|
||||
rc.right-rc.left, rc.bottom-rc.top,
|
||||
null, null, window_class.instance,
|
||||
null);
|
||||
nil, nil, window_class.instance,
|
||||
nil);
|
||||
|
||||
if win32_window == null {
|
||||
fmt.fprintln(os.stderr, "CreateWindowExA failed")
|
||||
return
|
||||
if win32_window == nil {
|
||||
fmt.fprintln(os.stderr, "CreateWindowExA failed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
window_bmi: BITMAPINFO;
|
||||
window_bmi.size = size_of(BITMAPINFO.HEADER) as u32
|
||||
window_bmi.width = CANVAS_WIDTH
|
||||
window_bmi.height = CANVAS_HEIGHT
|
||||
window_bmi.planes = 1
|
||||
window_bmi.bit_count = 32
|
||||
window_bmi.compression = BI_RGB
|
||||
window_bmi.size = size_of(BITMAPINFO.HEADER) as u32;
|
||||
window_bmi.width = CANVAS_WIDTH;
|
||||
window_bmi.height = CANVAS_HEIGHT;
|
||||
window_bmi.planes = 1;
|
||||
window_bmi.bit_count = 32;
|
||||
window_bmi.compression = BI_RGB;
|
||||
|
||||
|
||||
user_init(^_core)
|
||||
user_init(^_core);
|
||||
|
||||
|
||||
ShowWindow(win32_window, SW_SHOW)
|
||||
ShowWindow(win32_window, SW_SHOW);
|
||||
|
||||
window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT);
|
||||
assert(window_buffer.data != null)
|
||||
defer free(window_buffer.data)
|
||||
assert(window_buffer.data != nil);
|
||||
defer free(window_buffer.data);
|
||||
|
||||
for i := 0; i < window_buffer.count; i++ {
|
||||
window_buffer[i] = 0xff00ff
|
||||
window_buffer[i] = 0xff00ff;
|
||||
}
|
||||
|
||||
|
||||
prev_time, curr_time,dt: f64
|
||||
prev_time = time_now()
|
||||
curr_time = time_now()
|
||||
total_time : f64 = 0
|
||||
prev_time, curr_time,dt: f64;
|
||||
prev_time = time_now();
|
||||
curr_time = time_now();
|
||||
total_time : f64 = 0;
|
||||
offset_x := 0;
|
||||
offset_y := 0;
|
||||
|
||||
message: MSG
|
||||
message: MSG;
|
||||
for _core.running {
|
||||
curr_time = time_now()
|
||||
dt = curr_time - prev_time
|
||||
prev_time = curr_time
|
||||
total_time += dt
|
||||
curr_time = time_now();
|
||||
dt = curr_time - prev_time;
|
||||
prev_time = curr_time;
|
||||
total_time += dt;
|
||||
|
||||
offset_x += 1
|
||||
offset_y += 2
|
||||
offset_x += 1;
|
||||
offset_y += 2;
|
||||
|
||||
{
|
||||
data: [128]byte
|
||||
buf := data[:0]
|
||||
fmt.bprintf(^buf, "Punity: % ms\x00", dt*1000)
|
||||
win32.SetWindowTextA(win32_window, buf.data)
|
||||
data: [128]byte;
|
||||
buf := data[:0];
|
||||
fmt.bprintf(^buf, "Punity: % ms\x00", dt*1000);
|
||||
win32.SetWindowTextA(win32_window, buf.data);
|
||||
}
|
||||
|
||||
|
||||
for y := 0; y < CANVAS_HEIGHT; y++ {
|
||||
for x := 0; x < CANVAS_WIDTH; x++ {
|
||||
g := (x % 32) * 8
|
||||
b := (y % 32) * 8
|
||||
window_buffer[x + y*CANVAS_WIDTH] = (g << 8 | b) as u32
|
||||
g := (x % 32) * 8;
|
||||
b := (y % 32) * 8;
|
||||
window_buffer[x + y*CANVAS_WIDTH] = (g << 8 | b) as u32;
|
||||
}
|
||||
}
|
||||
|
||||
memory_zero(^_core.key_deltas[0], size_of_val(_core.key_deltas[0]))
|
||||
_core.key_deltas = nil;
|
||||
|
||||
|
||||
for PeekMessageA(^message, null, 0, 0, PM_REMOVE) != 0 {
|
||||
for PeekMessageA(^message, nil, 0, 0, PM_REMOVE) != 0 {
|
||||
if message.message == WM_QUIT {
|
||||
_core.running = false
|
||||
_core.running = false;
|
||||
}
|
||||
TranslateMessage(^message)
|
||||
DispatchMessageA(^message)
|
||||
TranslateMessage(^message);
|
||||
DispatchMessageA(^message);
|
||||
}
|
||||
|
||||
user_step(^_core)
|
||||
user_step(^_core);
|
||||
|
||||
dc := GetDC(win32_window);
|
||||
StretchDIBits(dc,
|
||||
@@ -467,18 +465,18 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
||||
window_buffer.data,
|
||||
^window_bmi,
|
||||
DIB_RGB_COLORS,
|
||||
SRCCOPY)
|
||||
ReleaseDC(win32_window, dc)
|
||||
SRCCOPY);
|
||||
ReleaseDC(win32_window, dc);
|
||||
|
||||
|
||||
{
|
||||
delta := time_now() - prev_time
|
||||
ms := ((FRAME_TIME - delta) * 1000) as i32
|
||||
delta := time_now() - prev_time;
|
||||
ms := ((FRAME_TIME - delta) * 1000) as i32;
|
||||
if ms > 0 {
|
||||
win32.Sleep(ms)
|
||||
win32.Sleep(ms);
|
||||
}
|
||||
}
|
||||
|
||||
_core.frame++
|
||||
_core.frame++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ thing :: proc() {
|
||||
*/
|
||||
|
||||
/*
|
||||
#load "fmt.odin"
|
||||
#include "fmt.odin"
|
||||
|
||||
thing :: proc() {
|
||||
println("Hello5!")
|
||||
|
||||
Reference in New Issue
Block a user