mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Update old demos
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
release_mode=0
|
release_mode=0
|
||||||
|
|
||||||
warnings_to_disable="-std=c++11 -g -Wno-switch -Wno-pointer-sign -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare -Wno-macro-redefined"
|
warnings_to_disable="-std=c++11 -g -Wno-switch -Wno-pointer-sign -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare -Wno-macro-redefined -Wno-writable-strings"
|
||||||
libraries="-pthread -ldl -lm -lstdc++"
|
libraries="-pthread -ldl -lm -lstdc++"
|
||||||
other_args=""
|
other_args=""
|
||||||
compiler="clang"
|
compiler="clang"
|
||||||
|
|||||||
+2
-1
@@ -16,5 +16,6 @@ proc main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.printf("The program \"%s\" calculates the value %d\n", program, accumulator);
|
fmt.printf("The program \"%s\" calculates the value %d\n",
|
||||||
|
program, accumulator);
|
||||||
}
|
}
|
||||||
|
|||||||
+78
-78
@@ -1,38 +1,37 @@
|
|||||||
#import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||||
#import wgl "sys/wgl.odin" when ODIN_OS == "windows";
|
import wgl "sys/wgl.odin" when ODIN_OS == "windows";
|
||||||
#import "fmt.odin";
|
import "fmt.odin";
|
||||||
#import "math.odin";
|
import "math.odin";
|
||||||
#import "os.odin";
|
import "os.odin";
|
||||||
#import gl "opengl.odin";
|
import gl "opengl.odin";
|
||||||
|
|
||||||
TWO_HEARTS :: '💕';
|
const TWO_HEARTS = '💕';
|
||||||
|
|
||||||
win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
|
var win32_perf_count_freq = win32.get_query_performance_frequency();
|
||||||
time_now :: proc() -> f64 {
|
proc time_now() -> f64 {
|
||||||
assert(win32_perf_count_freq != 0);
|
assert(win32_perf_count_freq != 0);
|
||||||
|
|
||||||
counter: i64;
|
var counter: i64;
|
||||||
win32.QueryPerformanceCounter(^counter);
|
win32.query_performance_counter(&counter);
|
||||||
result := cast(f64)counter / cast(f64)win32_perf_count_freq;
|
return f64(counter) / f64(win32_perf_count_freq);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
win32_print_last_error :: proc() {
|
proc win32_print_last_error() {
|
||||||
err_code := cast(int)win32.GetLastError();
|
var err_code = win32.get_last_error();
|
||||||
if err_code != 0 {
|
if err_code != 0 {
|
||||||
fmt.println("GetLastError: %", err_code);
|
fmt.println("get_last_error: ", err_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yuk!
|
// Yuk!
|
||||||
to_c_string :: proc(s: string) -> []u8 {
|
proc to_c_string(s: string) -> []u8 {
|
||||||
c_str := make([]u8, len(s)+1);
|
var c_str = make([]u8, len(s)+1);
|
||||||
copy(c_str, cast([]byte)s);
|
copy(c_str, []u8(s));
|
||||||
c_str[len(s)] = 0;
|
c_str[len(s)] = 0;
|
||||||
return c_str;
|
return c_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Window :: struct {
|
type Window struct {
|
||||||
width, height: int,
|
width, height: int,
|
||||||
wc: win32.WndClassExA,
|
wc: win32.WndClassExA,
|
||||||
dc: win32.Hdc,
|
dc: win32.Hdc,
|
||||||
@@ -41,52 +40,52 @@ Window :: struct {
|
|||||||
c_title: []u8,
|
c_title: []u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc) -> (Window, bool) {
|
proc make_window(title: string, msg, height: int, window_proc: win32.WndProc) -> (Window, bool) {
|
||||||
using win32;
|
using win32;
|
||||||
|
|
||||||
w: Window;
|
var w: Window;
|
||||||
w.width, w.height = msg, height;
|
w.width, w.height = msg, height;
|
||||||
|
|
||||||
class_name := "Win32-Odin-Window\x00";
|
var class_name = "Win32-Odin-Window\x00";
|
||||||
c_class_name := ^class_name[0];
|
var c_class_name = &class_name[0];
|
||||||
if title[len(title)-1] != 0 {
|
if title[len(title)-1] != 0 {
|
||||||
w.c_title = to_c_string(title);
|
w.c_title = to_c_string(title);
|
||||||
} else {
|
} else {
|
||||||
w.c_title = cast([]u8)title;
|
w.c_title = []u8(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance := GetModuleHandleA(nil);
|
var instance = get_module_handle_a(nil);
|
||||||
|
|
||||||
w.wc = WndClassExA{
|
w.wc = WndClassExA{
|
||||||
size = size_of(WndClassExA),
|
size = size_of(WndClassExA),
|
||||||
style = CS_VREDRAW | CS_HREDRAW,
|
style = CS_VREDRAW | CS_HREDRAW,
|
||||||
instance = cast(Hinstance)instance,
|
instance = Hinstance(instance),
|
||||||
class_name = c_class_name,
|
class_name = c_class_name,
|
||||||
wnd_proc = window_proc,
|
wnd_proc = window_proc,
|
||||||
};
|
};
|
||||||
|
|
||||||
if RegisterClassExA(^w.wc) == 0 {
|
if register_class_ex_a(&w.wc) == 0 {
|
||||||
win32_print_last_error();
|
win32_print_last_error();
|
||||||
return w, false;
|
return w, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
w.hwnd = CreateWindowExA(0,
|
w.hwnd = create_window_ex_a(0,
|
||||||
c_class_name, ^w.c_title[0],
|
c_class_name, &w.c_title[0],
|
||||||
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
cast(i32)w.width, cast(i32)w.height,
|
i32(w.width), i32(w.height),
|
||||||
nil, nil, instance, nil);
|
nil, nil, instance, nil);
|
||||||
|
|
||||||
if w.hwnd == nil {
|
if w.hwnd == nil {
|
||||||
win32_print_last_error();
|
win32_print_last_error();
|
||||||
return w, false;
|
return w, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
w.dc = GetDC(w.hwnd);
|
w.dc = get_dc(w.hwnd);
|
||||||
|
|
||||||
{
|
{
|
||||||
pfd := PIXELFORMATDESCRIPTOR{
|
var pfd = PixelFormatDescriptor{
|
||||||
size = size_of(PIXELFORMATDESCRIPTOR),
|
size = size_of(PixelFormatDescriptor),
|
||||||
version = 1,
|
version = 1,
|
||||||
flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
||||||
pixel_type = PFD_TYPE_RGBA,
|
pixel_type = PFD_TYPE_RGBA,
|
||||||
@@ -97,88 +96,89 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc
|
|||||||
layer_type = PFD_MAIN_PLANE,
|
layer_type = PFD_MAIN_PLANE,
|
||||||
};
|
};
|
||||||
|
|
||||||
SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil);
|
set_pixel_format(w.dc, choose_pixel_format(w.dc, &pfd), nil);
|
||||||
w.opengl_context = wgl.CreateContext(w.dc);
|
w.opengl_context = wgl.create_context(w.dc);
|
||||||
wgl.MakeCurrent(w.dc, w.opengl_context);
|
wgl.make_current(w.dc, w.opengl_context);
|
||||||
|
|
||||||
attribs := [8]i32{
|
var attribs = [8]i32{
|
||||||
wgl.CONTEXT_MAJOR_VERSION_ARB, 2,
|
wgl.CONTEXT_MAJOR_VERSION_ARB, 2,
|
||||||
wgl.CONTEXT_MINOR_VERSION_ARB, 1,
|
wgl.CONTEXT_MINOR_VERSION_ARB, 1,
|
||||||
wgl.CONTEXT_PROFILE_MASK_ARB, wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
wgl.CONTEXT_PROFILE_MASK_ARB, wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||||
0, // NOTE(bill): tells the proc that this is the end of attribs
|
0, // NOTE(bill): tells the proc that this is the end of attribs
|
||||||
};
|
};
|
||||||
|
|
||||||
wgl_str := "wglCreateContextAttribsARB\x00";
|
var wgl_str = "wglCreateContextAttribsARB\x00";
|
||||||
wglCreateContextAttribsARB := cast(wgl.Create_Context_Attribs_ARB_Type)wgl.GetProcAddress(^wgl_str[0]);
|
var wglCreateContextAttribsARB = wgl.CreateContextAttribsARBType(wgl.get_proc_address(&wgl_str[0]));
|
||||||
w.rc = wglCreateContextAttribsARB(w.dc, nil, ^attribs[0]);
|
w.rc = wglCreateContextAttribsARB(w.dc, nil, &attribs[0]);
|
||||||
wgl.MakeCurrent(w.dc, w.rc);
|
wgl.make_current(w.dc, w.rc);
|
||||||
SwapBuffers(w.dc);
|
swap_buffers(w.dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return w, true;
|
return w, true;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_window :: proc(w: ^Window) {
|
proc destroy_window(w: ^Window) {
|
||||||
free(w.c_title);
|
free(w.c_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
display_window :: proc(w: ^Window) {
|
proc display_window(w: ^Window) {
|
||||||
win32.SwapBuffers(w.dc);
|
win32.swap_buffers(w.dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
run :: proc() {
|
proc run() {
|
||||||
using win32;
|
|
||||||
using math;
|
using math;
|
||||||
|
|
||||||
win32_proc :: proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline {
|
proc win32_proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline {
|
||||||
|
using win32;
|
||||||
if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT {
|
if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT {
|
||||||
os.exit(0);
|
os.exit(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
return def_window_proc_a(hwnd, msg, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
window, window_success := make_window("Odin Language Demo", 854, 480, cast(Wnd_Proc)win32_proc);
|
var window, window_success = make_window("Odin Language Demo", 854, 480, win32.WndProc(win32_proc));
|
||||||
if !window_success {
|
if !window_success {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
defer destroy_window(^window);
|
defer destroy_window(&window);
|
||||||
|
|
||||||
gl.init();
|
gl.init();
|
||||||
|
|
||||||
|
using win32;
|
||||||
|
|
||||||
prev_time := time_now();
|
var prev_time = time_now();
|
||||||
running := true;
|
var running = true;
|
||||||
|
|
||||||
pos := Vec2{100, 100};
|
var pos = Vec2{100, 100};
|
||||||
|
|
||||||
for running {
|
for running {
|
||||||
curr_time := time_now();
|
var curr_time = time_now();
|
||||||
dt := cast(f32)(curr_time - prev_time);
|
var dt = f32(curr_time - prev_time);
|
||||||
prev_time = curr_time;
|
prev_time = curr_time;
|
||||||
|
|
||||||
msg: Msg;
|
var msg: Msg;
|
||||||
for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 {
|
for peek_message_a(&msg, nil, 0, 0, PM_REMOVE) > 0 {
|
||||||
if msg.message == WM_QUIT {
|
if msg.message == WM_QUIT {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
TranslateMessage(^msg);
|
translate_message(&msg);
|
||||||
DispatchMessageA(^msg);
|
dispatch_message_a(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_key_down(Key_Code.ESCAPE) {
|
if is_key_down(KeyCode.Escape) {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SPEED :: 500;
|
const SPEED = 500;
|
||||||
v: Vec2;
|
var v: Vec2;
|
||||||
|
|
||||||
if is_key_down(Key_Code.RIGHT) { v[0] += 1; }
|
if is_key_down(KeyCode.Right) { v[0] += 1; }
|
||||||
if is_key_down(Key_Code.LEFT) { v[0] -= 1; }
|
if is_key_down(KeyCode.Left) { v[0] -= 1; }
|
||||||
if is_key_down(Key_Code.UP) { v[1] += 1; }
|
if is_key_down(KeyCode.Up) { v[1] += 1; }
|
||||||
if is_key_down(Key_Code.DOWN) { v[1] -= 1; }
|
if is_key_down(KeyCode.Down) { v[1] -= 1; }
|
||||||
|
|
||||||
v = norm(v);
|
v = norm(v);
|
||||||
|
|
||||||
@@ -190,10 +190,10 @@ run :: proc() {
|
|||||||
gl.Clear(gl.COLOR_BUFFER_BIT);
|
gl.Clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
gl.LoadIdentity();
|
gl.LoadIdentity();
|
||||||
gl.Ortho(0, cast(f64)window.width,
|
gl.Ortho(0, f64(window.width),
|
||||||
0, cast(f64)window.height, 0, 1);
|
0, f64(window.height), 0, 1);
|
||||||
|
|
||||||
draw_rect :: proc(x, y, w, h: f32) {
|
proc draw_rect(x, y, w, h: f32) {
|
||||||
gl.Begin(gl.TRIANGLES);
|
gl.Begin(gl.TRIANGLES);
|
||||||
defer gl.End();
|
defer gl.End();
|
||||||
|
|
||||||
@@ -208,15 +208,15 @@ run :: proc() {
|
|||||||
|
|
||||||
draw_rect(pos.x, pos.y, 50, 50);
|
draw_rect(pos.x, pos.y, 50, 50);
|
||||||
|
|
||||||
display_window(^window);
|
display_window(&window);
|
||||||
ms_to_sleep := cast(i32)(16 - 1000*dt);
|
var ms_to_sleep = i32(16 - 1000*dt);
|
||||||
if ms_to_sleep > 0 {
|
if ms_to_sleep > 0 {
|
||||||
win32.Sleep(ms_to_sleep);
|
win32.sleep(ms_to_sleep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
proc main() {
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
|
|||||||
+62
-58
@@ -1,12 +1,12 @@
|
|||||||
#import "fmt.odin";
|
import "fmt.odin";
|
||||||
|
|
||||||
#foreign_system_library ws2 "Ws2_32.lib" when ODIN_OS == "windows";
|
foreign_system_library ws2 "Ws2_32.lib" when ODIN_OS == "windows";
|
||||||
|
|
||||||
|
|
||||||
SOCKET :: #type uint;
|
type SOCKET uint;
|
||||||
INVALID_SOCKET :: ~(cast(SOCKET)0);
|
const INVALID_SOCKET = ~SOCKET(0);
|
||||||
|
|
||||||
AF :: enum i32 {
|
type AF enum i32 {
|
||||||
UNSPEC = 0, // unspecified
|
UNSPEC = 0, // unspecified
|
||||||
UNIX = 1, // local to host (pipes, portals)
|
UNIX = 1, // local to host (pipes, portals)
|
||||||
INET = 2, // internetwork: UDP, TCP, etc.
|
INET = 2, // internetwork: UDP, TCP, etc.
|
||||||
@@ -37,19 +37,22 @@ AF :: enum i32 {
|
|||||||
MAX = 26,
|
MAX = 26,
|
||||||
};
|
};
|
||||||
|
|
||||||
SOCK_STREAM :: 1;
|
const (
|
||||||
SOCKET_ERROR :: -1;
|
SOCK_STREAM = 1;
|
||||||
IPPROTO_TCP :: 6;
|
SOCKET_ERROR = -1;
|
||||||
AI_PASSIVE :: 0x0020;
|
IPPROTO_TCP = 6;
|
||||||
SOMAXCONN :: 128;
|
AI_PASSIVE = 0x0020;
|
||||||
|
SOMAXCONN = 128;
|
||||||
|
)
|
||||||
|
const (
|
||||||
|
SD_RECEIVE = 0;
|
||||||
|
SD_SEND = 1;
|
||||||
|
SD_BOTH = 2;
|
||||||
|
)
|
||||||
|
|
||||||
SD_RECEIVE :: 0;
|
const WSADESCRIPTION_LEN = 256;
|
||||||
SD_SEND :: 1;
|
const WSASYS_STATUS_LEN = 128;
|
||||||
SD_BOTH :: 2;
|
type WSADATA struct #ordered {
|
||||||
|
|
||||||
WSADESCRIPTION_LEN :: 256;
|
|
||||||
WSASYS_STATUS_LEN :: 128;
|
|
||||||
WSADATA :: struct #ordered {
|
|
||||||
version: i16,
|
version: i16,
|
||||||
high_version: i16,
|
high_version: i16,
|
||||||
|
|
||||||
@@ -57,12 +60,12 @@ WSADATA :: struct #ordered {
|
|||||||
// NOTE(bill): This is x64 ordering
|
// NOTE(bill): This is x64 ordering
|
||||||
max_sockets: u16,
|
max_sockets: u16,
|
||||||
max_udp_dg: u16,
|
max_udp_dg: u16,
|
||||||
vendor_info: ^byte,
|
vendor_info: ^u8,
|
||||||
description: [WSADESCRIPTION_LEN+1]byte,
|
description: [WSADESCRIPTION_LEN+1]u8,
|
||||||
system_status: [WSASYS_STATUS_LEN+1]byte,
|
system_status: [WSASYS_STATUS_LEN+1]u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
addrinfo :: struct #ordered {
|
type addrinfo struct #ordered {
|
||||||
flags: i32,
|
flags: i32,
|
||||||
family: i32,
|
family: i32,
|
||||||
socktype: i32,
|
socktype: i32,
|
||||||
@@ -73,52 +76,53 @@ addrinfo :: struct #ordered {
|
|||||||
next: ^addrinfo,
|
next: ^addrinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr :: struct #ordered {
|
type sockaddr struct #ordered {
|
||||||
family: u16,
|
family: u16,
|
||||||
data: [14]byte,
|
data: [14]u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreign ws2 {
|
||||||
WSAStartup :: proc(version_requested: i16, data: ^WSADATA) -> i32 #foreign ws2;
|
proc WSAStartup (version_requested: i16, data: ^WSADATA) -> i32;
|
||||||
WSACleanup :: proc() -> i32 #foreign ws2;
|
proc WSACleanup () -> i32;
|
||||||
getaddrinfo :: proc(node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32 #foreign ws2;
|
proc getaddrinfo (node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32;
|
||||||
freeaddrinfo :: proc(ai: ^addrinfo) #foreign ws2;
|
proc freeaddrinfo (ai: ^addrinfo);
|
||||||
socket :: proc(af, type_, protocol: i32) -> SOCKET #foreign ws2;
|
proc socket (af, type_, protocol: i32) -> SOCKET;
|
||||||
closesocket :: proc(s: SOCKET) -> i32 #foreign ws2;
|
proc closesocket (s: SOCKET) -> i32;
|
||||||
bind :: proc(s: SOCKET, name: ^sockaddr, name_len: i32) -> i32 #foreign ws2;
|
proc bind (s: SOCKET, name: ^sockaddr, name_len: i32) -> i32;
|
||||||
listen :: proc(s: SOCKET, back_log: i32) -> i32 #foreign ws2;
|
proc listen (s: SOCKET, back_log: i32) -> i32;
|
||||||
accept :: proc(s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET #foreign ws2;
|
proc accept (s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET;
|
||||||
recv :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32 #foreign ws2;
|
proc recv (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
|
||||||
send :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32 #foreign ws2;
|
proc send (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
|
||||||
shutdown :: proc(s: SOCKET, how: i32) -> i32 #foreign ws2;
|
proc shutdown (s: SOCKET, how: i32) -> i32;
|
||||||
WSAGetLastError :: proc() -> i32 #foreign ws2;
|
proc WSAGetLastError() -> i32;
|
||||||
|
}
|
||||||
to_c_string :: proc(s: string) -> ^byte {
|
proc to_c_string(s: string) -> ^u8 {
|
||||||
c_str := new_slice(byte, s.count+1);
|
var c_str = make([]u8, len(s)+1);
|
||||||
assert(c_str.data != nil);
|
copy(c_str, []u8(s));
|
||||||
copy(c_str, cast([]byte)s);
|
c_str[len(s)] = 0;
|
||||||
c_str[s.count] = 0;
|
return &c_str[0];
|
||||||
return c_str.data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run :: proc() {
|
proc run() {
|
||||||
wsa: WSADATA;
|
var (
|
||||||
res: ^addrinfo = nil;
|
wsa: WSADATA;
|
||||||
hints: addrinfo;
|
res: ^addrinfo = nil;
|
||||||
s, client: SOCKET;
|
hints: addrinfo;
|
||||||
|
s, client: SOCKET;
|
||||||
|
)
|
||||||
|
|
||||||
if WSAStartup(2 | (2 << 8), ^wsa) != 0 {
|
if WSAStartup(2 | (2 << 8), &wsa) != 0 {
|
||||||
fmt.println("WSAStartup failed: ", WSAGetLastError());
|
fmt.println("WSAStartup failed: ", WSAGetLastError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
defer WSACleanup();
|
defer WSACleanup();
|
||||||
|
|
||||||
hints.family = cast(i32)AF.INET;
|
hints.family = i32(AF.INET);
|
||||||
hints.socktype = SOCK_STREAM;
|
hints.socktype = SOCK_STREAM;
|
||||||
hints.protocol = IPPROTO_TCP;
|
hints.protocol = IPPROTO_TCP;
|
||||||
hints.flags = AI_PASSIVE;
|
hints.flags = AI_PASSIVE;
|
||||||
|
|
||||||
if getaddrinfo(nil, to_c_string("8080"), ^hints, ^res) != 0 {
|
if getaddrinfo(nil, to_c_string("8080"), &hints, &res) != 0 {
|
||||||
fmt.println("getaddrinfo failed: ", WSAGetLastError());
|
fmt.println("getaddrinfo failed: ", WSAGetLastError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -131,7 +135,7 @@ run :: proc() {
|
|||||||
}
|
}
|
||||||
defer closesocket(s);
|
defer closesocket(s);
|
||||||
|
|
||||||
bind(s, res.addr, cast(i32)res.addrlen);
|
bind(s, res.addr, i32(res.addrlen));
|
||||||
listen(s, SOMAXCONN);
|
listen(s, SOMAXCONN);
|
||||||
|
|
||||||
client = accept(s, nil, 0);
|
client = accept(s, nil, 0);
|
||||||
@@ -141,7 +145,7 @@ run :: proc() {
|
|||||||
}
|
}
|
||||||
defer closesocket(client);
|
defer closesocket(client);
|
||||||
|
|
||||||
html :=
|
var html =
|
||||||
`HTTP/1.1 200 OK
|
`HTTP/1.1 200 OK
|
||||||
Connection: close
|
Connection: close
|
||||||
Content-type: text/html
|
Content-type: text/html
|
||||||
@@ -156,12 +160,12 @@ Content-type: text/html
|
|||||||
</html>
|
</html>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
buf: [1024]byte;
|
var buf: [1024]u8;
|
||||||
for {
|
for {
|
||||||
bytes := recv(client, ^buf[0], cast(i32)buf.count, 0);
|
var bytes = recv(client, &buf[0], i32(len(buf)), 0);
|
||||||
if bytes > 0 {
|
if bytes > 0 {
|
||||||
// fmt.println(buf[:bytes] as string)
|
// fmt.println(string(buf[0..<bytes]))
|
||||||
bytes_sent := send(client, html.data, cast(i32)(html.count-1), 0);
|
var bytes_sent = send(client, &html[0], i32(len(html)-1), 0);
|
||||||
if bytes_sent == SOCKET_ERROR {
|
if bytes_sent == SOCKET_ERROR {
|
||||||
fmt.println("send failed: ", WSAGetLastError());
|
fmt.println("send failed: ", WSAGetLastError());
|
||||||
return;
|
return;
|
||||||
|
|||||||
+233
-224
@@ -1,35 +1,42 @@
|
|||||||
#import win32 "sys/windows.odin";
|
import (
|
||||||
#import "fmt.odin";
|
win32 "sys/windows.odin";
|
||||||
#import "os.odin";
|
"fmt.odin";
|
||||||
#import "mem.odin";
|
"os.odin";
|
||||||
|
"mem.odin";
|
||||||
|
)
|
||||||
|
|
||||||
CANVAS_WIDTH :: 128;
|
const (
|
||||||
CANVAS_HEIGHT :: 128;
|
CANVAS_WIDTH = 128;
|
||||||
CANVAS_SCALE :: 3;
|
CANVAS_HEIGHT = 128;
|
||||||
FRAME_TIME :: 1.0/30.0;
|
CANVAS_SCALE = 3;
|
||||||
WINDOW_TITLE :: "Punity\x00";
|
FRAME_TIME = 1.0/30.0;
|
||||||
|
WINDOW_TITLE = "Punity\x00";
|
||||||
|
)
|
||||||
|
|
||||||
_ := compile_assert(CANVAS_WIDTH % 16 == 0);
|
const _ = compile_assert(CANVAS_WIDTH % 16 == 0);
|
||||||
|
|
||||||
WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE;
|
const (
|
||||||
WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE;
|
WINDOW_WIDTH = CANVAS_WIDTH * CANVAS_SCALE;
|
||||||
|
WINDOW_HEIGHT = CANVAS_HEIGHT * CANVAS_SCALE;
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
STACK_CAPACITY = 1<<20;
|
||||||
|
STORAGE_CAPACITY = 1<<20;
|
||||||
|
|
||||||
STACK_CAPACITY :: 1<<20;
|
DRAW_LIST_RESERVE = 128;
|
||||||
STORAGE_CAPACITY :: 1<<20;
|
|
||||||
|
|
||||||
DRAW_LIST_RESERVE :: 128;
|
MAX_KEYS = 256;
|
||||||
|
)
|
||||||
|
|
||||||
MAX_KEYS :: 256;
|
type Core struct {
|
||||||
|
|
||||||
Core :: struct {
|
|
||||||
stack: ^Bank,
|
stack: ^Bank,
|
||||||
storage: ^Bank,
|
storage: ^Bank,
|
||||||
|
|
||||||
running: bool,
|
running: bool,
|
||||||
key_modifiers: u32,
|
key_modifiers: u32,
|
||||||
key_states: [MAX_KEYS]byte,
|
key_states: [MAX_KEYS]u8,
|
||||||
key_deltas: [MAX_KEYS]byte,
|
key_deltas: [MAX_KEYS]u8,
|
||||||
|
|
||||||
perf_frame,
|
perf_frame,
|
||||||
perf_frame_inner,
|
perf_frame_inner,
|
||||||
@@ -45,52 +52,52 @@ Core :: struct {
|
|||||||
draw_list: ^Draw_List,
|
draw_list: ^Draw_List,
|
||||||
}
|
}
|
||||||
|
|
||||||
Perf_Span :: struct {
|
type Perf_Span struct {
|
||||||
stamp: f64,
|
stamp: f64,
|
||||||
delta: f32,
|
delta: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
Bank :: struct {
|
type Bank struct {
|
||||||
memory: []byte,
|
memory: []u8,
|
||||||
cursor: int,
|
cursor: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Bank_State :: struct {
|
type Bank_State struct {
|
||||||
state: Bank,
|
state: Bank,
|
||||||
bank: ^Bank,
|
bank: ^Bank,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Color :: raw_union {
|
type Color raw_union {
|
||||||
using channels: struct{a, b, g, r: byte},
|
using channels: struct{a, b, g, r: u8},
|
||||||
rgba: u32,
|
rgba: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
Palette :: struct {
|
type Palette struct {
|
||||||
colors: [256]Color,
|
colors: [256]Color,
|
||||||
colors_count: byte,
|
colors_count: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rect :: raw_union {
|
type Rect raw_union {
|
||||||
using minmax: struct {min_x, min_y, max_x, max_y: int},
|
using minmax: struct {min_x, min_y, max_x, max_y: int},
|
||||||
using pos: struct {left, top, right, bottom: int},
|
using pos: struct {left, top, right, bottom: int},
|
||||||
e: [4]int,
|
e: [4]int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap :: struct {
|
type Bitmap struct {
|
||||||
pixels: []byte,
|
pixels: []u8,
|
||||||
width: int,
|
width: int,
|
||||||
height: int,
|
height: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Font :: struct {
|
type Font struct {
|
||||||
using bitmap: Bitmap,
|
using bitmap: Bitmap,
|
||||||
char_width: int,
|
char_width: int,
|
||||||
char_height: int,
|
char_height: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas :: struct {
|
type Canvas struct {
|
||||||
using bitmap: ^Bitmap,
|
using bitmap: ^Bitmap,
|
||||||
palette: Palette,
|
palette: Palette,
|
||||||
translate_x: int,
|
translate_x: int,
|
||||||
@@ -99,89 +106,92 @@ Canvas :: struct {
|
|||||||
font: ^Font,
|
font: ^Font,
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawFlag :: enum {
|
type DrawFlag enum {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
FLIP_H = 1<<0,
|
FLIP_H = 1<<0,
|
||||||
FLIP_V = 1<<1,
|
FLIP_V = 1<<1,
|
||||||
MASK = 1<<2,
|
MASK = 1<<2,
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw_Item :: struct {}
|
type Draw_Item struct {}
|
||||||
Draw_List :: struct {
|
type Draw_List struct {
|
||||||
items: []Draw_Item,
|
items: []Draw_Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
Key :: enum {
|
type Key enum {
|
||||||
MOD_SHIFT = 0x0001,
|
ModShift = 0x0001,
|
||||||
MOD_CONTROL = 0x0002,
|
ModControl = 0x0002,
|
||||||
MOD_ALT = 0x0004,
|
ModAlt = 0x0004,
|
||||||
MOD_SUPER = 0x0008,
|
ModSuper = 0x0008,
|
||||||
|
|
||||||
UNKNOWN =-1,
|
|
||||||
INVALID =-2,
|
|
||||||
|
|
||||||
LBUTTON = 1,
|
Unknown =-1,
|
||||||
RBUTTON = 2,
|
Invalid =-2,
|
||||||
CANCEL = 3,
|
|
||||||
MBUTTON = 4,
|
|
||||||
|
|
||||||
BACK = 8,
|
|
||||||
TAB = 9,
|
Lbutton = 1,
|
||||||
CLEAR = 12,
|
Rbutton = 2,
|
||||||
RETURN = 13,
|
Cancel = 3,
|
||||||
SHIFT = 16,
|
Mbutton = 4,
|
||||||
CONTROL = 17,
|
|
||||||
MENU = 18,
|
|
||||||
PAUSE = 19,
|
Back = 8,
|
||||||
CAPITAL = 20,
|
Tab = 9,
|
||||||
KANA = 0x15,
|
Clear = 12,
|
||||||
HANGEUL = 0x15,
|
Return = 13,
|
||||||
HANGUL = 0x15,
|
Shift = 16,
|
||||||
JUNJA = 0x17,
|
Control = 17,
|
||||||
FINAL = 0x18,
|
Menu = 18,
|
||||||
HANJA = 0x19,
|
Pause = 19,
|
||||||
KANJI = 0x19,
|
Capital = 20,
|
||||||
ESCAPE = 0x1B,
|
Kana = 0x15,
|
||||||
CONVERT = 0x1C,
|
Hangeul = 0x15,
|
||||||
NONCONVERT = 0x1D,
|
Hangul = 0x15,
|
||||||
ACCEPT = 0x1E,
|
Junja = 0x17,
|
||||||
MODECHANGE = 0x1F,
|
Final = 0x18,
|
||||||
SPACE = 32,
|
Hanja = 0x19,
|
||||||
PRIOR = 33,
|
Kanji = 0x19,
|
||||||
NEXT = 34,
|
Escape = 0x1B,
|
||||||
END = 35,
|
Convert = 0x1C,
|
||||||
HOME = 36,
|
NonConvert = 0x1D,
|
||||||
LEFT = 37,
|
Accept = 0x1E,
|
||||||
UP = 38,
|
ModeChange = 0x1F,
|
||||||
RIGHT = 39,
|
Space = 32,
|
||||||
DOWN = 40,
|
Prior = 33,
|
||||||
SELECT = 41,
|
Next = 34,
|
||||||
PRINT = 42,
|
End = 35,
|
||||||
EXEC = 43,
|
Home = 36,
|
||||||
SNAPSHOT = 44,
|
Left = 37,
|
||||||
INSERT = 45,
|
Up = 38,
|
||||||
DELETE = 46,
|
Right = 39,
|
||||||
HELP = 47,
|
Down = 40,
|
||||||
LWIN = 0x5B,
|
Select = 41,
|
||||||
RWIN = 0x5C,
|
Print = 42,
|
||||||
APPS = 0x5D,
|
Exec = 43,
|
||||||
SLEEP = 0x5F,
|
Snapshot = 44,
|
||||||
NUMPAD0 = 0x60,
|
Insert = 45,
|
||||||
NUMPAD1 = 0x61,
|
Delete = 46,
|
||||||
NUMPAD2 = 0x62,
|
Help = 47,
|
||||||
NUMPAD3 = 0x63,
|
Lwin = 0x5B,
|
||||||
NUMPAD4 = 0x64,
|
Rwin = 0x5C,
|
||||||
NUMPAD5 = 0x65,
|
Apps = 0x5D,
|
||||||
NUMPAD6 = 0x66,
|
Sleep = 0x5F,
|
||||||
NUMPAD7 = 0x67,
|
Numpad0 = 0x60,
|
||||||
NUMPAD8 = 0x68,
|
Numpad1 = 0x61,
|
||||||
NUMPAD9 = 0x69,
|
Numpad2 = 0x62,
|
||||||
MULTIPLY = 0x6A,
|
Numpad3 = 0x63,
|
||||||
ADD = 0x6B,
|
Numpad4 = 0x64,
|
||||||
SEPARATOR = 0x6C,
|
Numpad5 = 0x65,
|
||||||
SUBTRACT = 0x6D,
|
Numpad6 = 0x66,
|
||||||
DECIMAL = 0x6E,
|
Numpad7 = 0x67,
|
||||||
DIVIDE = 0x6F,
|
Numpad8 = 0x68,
|
||||||
|
Numpad9 = 0x69,
|
||||||
|
Multiply = 0x6A,
|
||||||
|
Add = 0x6B,
|
||||||
|
Separator = 0x6C,
|
||||||
|
Subtract = 0x6D,
|
||||||
|
Decimal = 0x6E,
|
||||||
|
Divide = 0x6F,
|
||||||
F1 = 0x70,
|
F1 = 0x70,
|
||||||
F2 = 0x71,
|
F2 = 0x71,
|
||||||
F3 = 0x72,
|
F3 = 0x72,
|
||||||
@@ -206,32 +216,33 @@ Key :: enum {
|
|||||||
F22 = 0x85,
|
F22 = 0x85,
|
||||||
F23 = 0x86,
|
F23 = 0x86,
|
||||||
F24 = 0x87,
|
F24 = 0x87,
|
||||||
NUMLOCK = 0x90,
|
Numlock = 0x90,
|
||||||
SCROLL = 0x91,
|
Scroll = 0x91,
|
||||||
LSHIFT = 0xA0,
|
Lshift = 0xA0,
|
||||||
RSHIFT = 0xA1,
|
Rshift = 0xA1,
|
||||||
LCONTROL = 0xA2,
|
Lcontrol = 0xA2,
|
||||||
RCONTROL = 0xA3,
|
Rcontrol = 0xA3,
|
||||||
LMENU = 0xA4,
|
Lmenu = 0xA4,
|
||||||
RMENU = 0xA5,
|
Rmenu = 0xA5,
|
||||||
|
|
||||||
APOSTROPHE = 39, /* ' */
|
|
||||||
COMMA = 44, /* , */
|
Apostrophe = 39, /* ' */
|
||||||
MINUS = 45, /* - */
|
Comma = 44, /* , */
|
||||||
PERIOD = 46, /* . */
|
Minus = 45, /* - */
|
||||||
SLASH = 47, /* / */
|
Period = 46, /* . */
|
||||||
NUM0 = 48,
|
Slash = 47, /* / */
|
||||||
NUM1 = 49,
|
Num0 = 48,
|
||||||
NUM2 = 50,
|
Num1 = 49,
|
||||||
NUM3 = 51,
|
Num2 = 50,
|
||||||
NUM4 = 52,
|
Num3 = 51,
|
||||||
NUM5 = 53,
|
Num4 = 52,
|
||||||
NUM6 = 54,
|
Num5 = 53,
|
||||||
NUM7 = 55,
|
Num6 = 54,
|
||||||
NUM8 = 56,
|
Num7 = 55,
|
||||||
NUM9 = 57,
|
Num8 = 56,
|
||||||
SEMICOLON = 59, /* ; */
|
Num9 = 57,
|
||||||
EQUAL = 61, /* = */
|
Semicolon = 59, /* ; */
|
||||||
|
Equal = 61, /* = */
|
||||||
A = 65,
|
A = 65,
|
||||||
B = 66,
|
B = 66,
|
||||||
C = 67,
|
C = 67,
|
||||||
@@ -258,56 +269,55 @@ Key :: enum {
|
|||||||
X = 88,
|
X = 88,
|
||||||
Y = 89,
|
Y = 89,
|
||||||
Z = 90,
|
Z = 90,
|
||||||
LEFT_BRACKET = 91, /* [ */
|
LeftBracket = 91, /* [ */
|
||||||
BACKSLASH = 92, /* \ */
|
Backslash = 92, /* \ */
|
||||||
RIGHT_BRACKET = 93, /* ] */
|
RightBracket = 93, /* ] */
|
||||||
GRAVE_ACCENT = 96, /* ` */
|
GraveAccent = 96, /* ` */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
key_down :: proc(k: Key) -> bool {
|
proc key_down(k: Key) -> bool {
|
||||||
return _core.key_states[k] != 0;
|
return _core.key_states[k] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_pressed :: proc(k: Key) -> bool {
|
proc key_pressed(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();
|
let win32_perf_count_freq = win32.get_query_performance_frequency();
|
||||||
time_now :: proc() -> f64 {
|
proc time_now() -> f64 {
|
||||||
assert(win32_perf_count_freq != 0);
|
assert(win32_perf_count_freq != 0);
|
||||||
|
|
||||||
counter: i64;
|
var counter: i64;
|
||||||
win32.QueryPerformanceCounter(^counter);
|
win32.query_performance_counter(&counter);
|
||||||
result := cast(f64)counter / cast(f64)win32_perf_count_freq;
|
return f64(counter) / f64(win32_perf_count_freq);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_core: Core;
|
var _core: Core;
|
||||||
|
|
||||||
run :: proc(user_init, user_step: proc(c: ^Core)) {
|
proc run(user_init, user_step: proc(c: ^Core)) {
|
||||||
using win32;
|
using win32;
|
||||||
|
|
||||||
_core.running = true;
|
_core.running = true;
|
||||||
|
|
||||||
win32_proc :: proc(hwnd: win32.HWND, msg: u32, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT #no_inline #cc_c {
|
proc win32_proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline #cc_c {
|
||||||
win32_app_key_mods :: proc() -> u32 {
|
proc win32_app_key_mods() -> u32 {
|
||||||
mods: u32 = 0;
|
var mods: u32 = 0;
|
||||||
|
|
||||||
if is_key_down(Key_Code.SHIFT) {
|
if is_key_down(KeyCode.Shift) {
|
||||||
mods |= cast(u32)Key.MOD_SHIFT;
|
mods |= u32(Key.ModShift);
|
||||||
}
|
}
|
||||||
if is_key_down(Key_Code.CONTROL) {
|
if is_key_down(KeyCode.Control) {
|
||||||
mods |= cast(u32)Key.MOD_CONTROL;
|
mods |= u32(Key.ModControl);
|
||||||
}
|
}
|
||||||
if is_key_down(Key_Code.MENU) {
|
if is_key_down(KeyCode.Menu) {
|
||||||
mods |= cast(u32)Key.MOD_ALT;
|
mods |= u32(Key.ModAlt);
|
||||||
}
|
}
|
||||||
if is_key_down(Key_Code.LWIN) || is_key_down(Key_Code.RWIN) {
|
if is_key_down(KeyCode.Lwin) || is_key_down(KeyCode.Rwin) {
|
||||||
mods |= cast(u32)Key.MOD_SUPER;
|
mods |= u32(Key.ModSuper);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mods;
|
return mods;
|
||||||
@@ -331,61 +341,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
PostQuitMessage(0);
|
post_quit_message(0);
|
||||||
_core.running = false;
|
_core.running = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
return def_window_proc_a(hwnd, msg, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window_class := WNDCLASSEXA{
|
var class_name = "Punity\x00";
|
||||||
class_name = (cast(string)"Punity\x00").data, // C-style string
|
var window_class = WndClassExA{
|
||||||
size = size_of(WNDCLASSEXA),
|
class_name = &class_name[0],
|
||||||
|
size = size_of(WndClassExA),
|
||||||
style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||||
instance = cast(HINSTANCE)GetModuleHandleA(nil),
|
instance = Hinstance(get_module_handle_a(nil)),
|
||||||
wnd_proc = win32_proc,
|
wnd_proc = win32_proc,
|
||||||
// wnd_proc = DefWindowProcA,
|
// wnd_proc = DefWindowProcA,
|
||||||
background = cast(HBRUSH)GetStockObject(BLACK_BRUSH),
|
background = Hbrush(get_stock_object(BLACK_BRUSH)),
|
||||||
};
|
};
|
||||||
|
|
||||||
if RegisterClassExA(^window_class) == 0 {
|
if register_class_ex_a(&window_class) == 0 {
|
||||||
fmt.fprintln(os.stderr, "RegisterClassExA failed");
|
fmt.fprintln(os.stderr, "register_class_ex_a failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_width := GetSystemMetrics(SM_CXSCREEN);
|
var screen_width = get_system_metrics(SM_CXSCREEN);
|
||||||
screen_height := GetSystemMetrics(SM_CYSCREEN);
|
var screen_height = get_system_metrics(SM_CYSCREEN);
|
||||||
|
|
||||||
rc: RECT;
|
var rc: Rect;
|
||||||
rc.left = (screen_width - WINDOW_WIDTH) / 2;
|
rc.left = (screen_width - WINDOW_WIDTH) / 2;
|
||||||
rc.top = (screen_height - WINDOW_HEIGHT) / 2;
|
rc.top = (screen_height - WINDOW_HEIGHT) / 2;
|
||||||
rc.right = rc.left + WINDOW_WIDTH;
|
rc.right = rc.left + WINDOW_WIDTH;
|
||||||
rc.bottom = rc.top + WINDOW_HEIGHT;
|
rc.bottom = rc.top + WINDOW_HEIGHT;
|
||||||
|
|
||||||
style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
var style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||||
assert(AdjustWindowRect(^rc, style, 0) != 0);
|
assert(adjust_window_rect(&rc, style, 0) != 0);
|
||||||
|
|
||||||
wt := WINDOW_TITLE;
|
var wt = WINDOW_TITLE;
|
||||||
|
|
||||||
win32_window := CreateWindowExA(0,
|
var win32_window = create_window_ex_a(0,
|
||||||
window_class.class_name,
|
window_class.class_name,
|
||||||
wt.data,
|
&wt[0],
|
||||||
style,
|
style,
|
||||||
rc.left, rc.top,
|
rc.left, rc.top,
|
||||||
rc.right-rc.left, rc.bottom-rc.top,
|
rc.right-rc.left, rc.bottom-rc.top,
|
||||||
nil, nil, window_class.instance,
|
nil, nil, window_class.instance,
|
||||||
nil);
|
nil);
|
||||||
|
|
||||||
if win32_window == nil {
|
if win32_window == nil {
|
||||||
fmt.fprintln(os.stderr, "CreateWindowExA failed");
|
fmt.fprintln(os.stderr, "create_window_ex_a failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window_bmi: BITMAPINFO;
|
var window_bmi: BitmapInfo;
|
||||||
window_bmi.size = size_of(BITMAPINFOHEADER);
|
window_bmi.size = size_of(BitmapInfoHeader);
|
||||||
window_bmi.width = CANVAS_WIDTH;
|
window_bmi.width = CANVAS_WIDTH;
|
||||||
window_bmi.height = CANVAS_HEIGHT;
|
window_bmi.height = CANVAS_HEIGHT;
|
||||||
window_bmi.planes = 1;
|
window_bmi.planes = 1;
|
||||||
@@ -393,27 +404,27 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
|||||||
window_bmi.compression = BI_RGB;
|
window_bmi.compression = BI_RGB;
|
||||||
|
|
||||||
|
|
||||||
user_init(^_core);
|
user_init(&_core);
|
||||||
|
|
||||||
ShowWindow(win32_window, SW_SHOW);
|
show_window(win32_window, SW_SHOW);
|
||||||
|
|
||||||
window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT);
|
var window_buffer = make([]u32, CANVAS_WIDTH * CANVAS_HEIGHT);
|
||||||
defer free(window_buffer);
|
defer free(window_buffer);
|
||||||
|
|
||||||
|
for _, i in window_buffer {
|
||||||
for i := 0; i < window_buffer.count; i += 1 {
|
|
||||||
window_buffer[i] = 0xff00ff;
|
window_buffer[i] = 0xff00ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
dt: f64;
|
||||||
|
prev_time = time_now();
|
||||||
|
curr_time = time_now();
|
||||||
|
total_time : f64 = 0;
|
||||||
|
offset_x = 0;
|
||||||
|
offset_y = 0;
|
||||||
|
)
|
||||||
|
|
||||||
dt: f64;
|
var message: Msg;
|
||||||
prev_time := time_now();
|
|
||||||
curr_time := time_now();
|
|
||||||
total_time : f64 = 0;
|
|
||||||
offset_x := 0;
|
|
||||||
offset_y := 0;
|
|
||||||
|
|
||||||
message: MSG;
|
|
||||||
for _core.running {
|
for _core.running {
|
||||||
curr_time = time_now();
|
curr_time = time_now();
|
||||||
dt = curr_time - prev_time;
|
dt = curr_time - prev_time;
|
||||||
@@ -424,64 +435,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
|||||||
offset_y += 2;
|
offset_y += 2;
|
||||||
|
|
||||||
{
|
{
|
||||||
data: [128]byte;
|
var buf: [128]u8;
|
||||||
buf: fmt.Buffer;
|
var s = fmt.bprintf(buf[..], "Punity: %.4f ms\x00", dt*1000);
|
||||||
buf.data = data[:];
|
win32.set_window_text_a(win32_window, &s[0]);
|
||||||
fmt.bprintf(^buf, "Punity: %.4f ms\x00", dt*1000);
|
|
||||||
win32.SetWindowTextA(win32_window, ^buf[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for y := 0; y < CANVAS_HEIGHT; y += 1 {
|
for var y = 0; y < CANVAS_HEIGHT; y++ {
|
||||||
for x := 0; x < CANVAS_WIDTH; x += 1 {
|
for var x = 0; x < CANVAS_WIDTH; x++ {
|
||||||
g := (x % 32) * 8;
|
var g = (x % 32) * 8;
|
||||||
b := (y % 32) * 8;
|
var b = (y % 32) * 8;
|
||||||
window_buffer[x + y*CANVAS_WIDTH] = cast(u32)(g << 8 | b);
|
window_buffer[x + y*CANVAS_WIDTH] = u32(g << 8 | b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mem.zero(^_core.key_deltas[0], size_of_val(_core.key_deltas));
|
mem.zero(&_core.key_deltas[0], size_of(_core.key_deltas));
|
||||||
|
|
||||||
for PeekMessageA(^message, nil, 0, 0, PM_REMOVE) != 0 {
|
for peek_message_a(&message, nil, 0, 0, PM_REMOVE) != 0 {
|
||||||
if message.message == WM_QUIT {
|
if message.message == WM_QUIT {
|
||||||
_core.running = false;
|
_core.running = false;
|
||||||
}
|
}
|
||||||
TranslateMessage(^message);
|
translate_message(&message);
|
||||||
DispatchMessageA(^message);
|
dispatch_message_a(&message);
|
||||||
}
|
}
|
||||||
|
|
||||||
user_step(^_core);
|
user_step(&_core);
|
||||||
|
|
||||||
dc := GetDC(win32_window);
|
var dc = get_dc(win32_window);
|
||||||
StretchDIBits(dc,
|
stretch_dibits(dc,
|
||||||
0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
|
0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
|
||||||
0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
|
0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
|
||||||
window_buffer.data,
|
&window_buffer[0],
|
||||||
^window_bmi,
|
&window_bmi,
|
||||||
DIB_RGB_COLORS,
|
DIB_RGB_COLORS,
|
||||||
SRCCOPY);
|
SRCCOPY);
|
||||||
ReleaseDC(win32_window, dc);
|
release_dc(win32_window, dc);
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
delta := time_now() - prev_time;
|
var delta = time_now() - prev_time;
|
||||||
ms := cast(i32)((FRAME_TIME - delta) * 1000);
|
var ms = i32((FRAME_TIME - delta) * 1000);
|
||||||
if ms > 0 {
|
if ms > 0 {
|
||||||
win32.Sleep(ms);
|
win32.sleep(ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_core.frame += 1;
|
_core.frame++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
proc main() {
|
||||||
user_init :: proc(c: ^Core) {
|
proc user_init(c: ^Core) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user_step :: proc(c: ^Core) {
|
proc user_step(c: ^Core) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
#import "fmt.odin" as fmt
|
|
||||||
|
|
||||||
thing :: proc() {
|
|
||||||
fmt.println("Sub Hello!")
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*#import "fmt.odin"
|
|
||||||
|
|
||||||
thing :: proc() {
|
|
||||||
fmt.println("Hello1!")
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
#import "fmt.odin";
|
|
||||||
|
|
||||||
main :: proc() {
|
|
||||||
fmt.println("hello, world!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*#import "fmt.odin" as .
|
|
||||||
|
|
||||||
thing :: proc() {
|
|
||||||
println("Hello3!")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
/*#import "fmt.odin" as _
|
|
||||||
|
|
||||||
thing :: proc() {
|
|
||||||
// println("Hello4!")
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include "fmt.odin"
|
|
||||||
|
|
||||||
thing :: proc() {
|
|
||||||
println("Hello5!")
|
|
||||||
}*/
|
|
||||||
+2
-2
@@ -681,8 +681,8 @@ void i128_divide(i128 a, i128 b, i128 *quo, i128 *rem) {
|
|||||||
i128 ni = *cast(i128 *)&n;
|
i128 ni = *cast(i128 *)&n;
|
||||||
i128 ri = *cast(i128 *)&r;
|
i128 ri = *cast(i128 *)&r;
|
||||||
|
|
||||||
if (quo) *quo = i128_sub(i128_xor(ri, s), s);
|
if (quo) *quo = i128_sub(i128_xor(ni, s), s);
|
||||||
if (rem) *rem = i128_sub(i128_xor(ni, s), s);
|
if (rem) *rem = i128_sub(i128_xor(ri, s), s);
|
||||||
#else
|
#else
|
||||||
if (i128_eq(b, I128_ZERO)) {
|
if (i128_eq(b, I128_ZERO)) {
|
||||||
if (quo) *quo = i128_from_u64(a.lo/b.lo);
|
if (quo) *quo = i128_from_u64(a.lo/b.lo);
|
||||||
|
|||||||
+1
-4
@@ -1665,10 +1665,6 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
ir_fprintf(f, " = type {float, float} ; Basic_complex64\n");
|
ir_fprintf(f, " = type {float, float} ; Basic_complex64\n");
|
||||||
ir_print_encoded_local(f, str_lit("..complex128"));
|
ir_print_encoded_local(f, str_lit("..complex128"));
|
||||||
ir_fprintf(f, " = type {double, double} ; Basic_complex128\n");
|
ir_fprintf(f, " = type {double, double} ; Basic_complex128\n");
|
||||||
ir_print_encoded_local(f, str_lit("..quaternion128"));
|
|
||||||
ir_fprintf(f, " = type {float, float, float, float} ; Basic_quaternion128\n");
|
|
||||||
ir_print_encoded_local(f, str_lit("..quaternion256"));
|
|
||||||
ir_fprintf(f, " = type {double, double, double, double} ; Basic_quaternion256\n");
|
|
||||||
|
|
||||||
|
|
||||||
ir_print_encoded_local(f, str_lit("..any"));
|
ir_print_encoded_local(f, str_lit("..any"));
|
||||||
@@ -1679,6 +1675,7 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
ir_fprintf(f, "} ; Basic_any\n");
|
ir_fprintf(f, "} ; Basic_any\n");
|
||||||
|
|
||||||
ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");
|
ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");
|
||||||
|
ir_fprintf(f, "\n");
|
||||||
|
|
||||||
|
|
||||||
for_array(member_index, m->members.entries) {
|
for_array(member_index, m->members.entries) {
|
||||||
|
|||||||
+49
-24
@@ -339,14 +339,14 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
|
|||||||
Array<AstNode *> names; \
|
Array<AstNode *> names; \
|
||||||
AstNode * type; \
|
AstNode * type; \
|
||||||
Array<AstNode *> values; \
|
Array<AstNode *> values; \
|
||||||
CommentGroup docs; \
|
CommentGroup docs; \
|
||||||
CommentGroup comment; \
|
CommentGroup comment; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(TypeSpec, "type specification", struct { \
|
AST_NODE_KIND(TypeSpec, "type specification", struct { \
|
||||||
AstNode *name; \
|
AstNode *name; \
|
||||||
AstNode *type; \
|
AstNode *type; \
|
||||||
CommentGroup docs; \
|
CommentGroup docs; \
|
||||||
CommentGroup comment; \
|
CommentGroup comment; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(ImportSpec, "import specification", struct { \
|
AST_NODE_KIND(ImportSpec, "import specification", struct { \
|
||||||
bool is_import; \
|
bool is_import; \
|
||||||
@@ -354,8 +354,8 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
|
|||||||
String fullpath; \
|
String fullpath; \
|
||||||
Token import_name; \
|
Token import_name; \
|
||||||
AstNode *cond; \
|
AstNode *cond; \
|
||||||
CommentGroup docs; \
|
CommentGroup docs; \
|
||||||
CommentGroup comment; \
|
CommentGroup comment; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(ForeignLibrarySpec, "foreign library specification", struct { \
|
AST_NODE_KIND(ForeignLibrarySpec, "foreign library specification", struct { \
|
||||||
Token filepath; \
|
Token filepath; \
|
||||||
@@ -363,8 +363,8 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
|
|||||||
String base_dir; \
|
String base_dir; \
|
||||||
AstNode *cond; \
|
AstNode *cond; \
|
||||||
bool is_system; \
|
bool is_system; \
|
||||||
CommentGroup docs; \
|
CommentGroup docs; \
|
||||||
CommentGroup comment; \
|
CommentGroup comment; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(_DeclEnd, "", i32) \
|
AST_NODE_KIND(_DeclEnd, "", i32) \
|
||||||
AST_NODE_KIND(Field, "field", struct { \
|
AST_NODE_KIND(Field, "field", struct { \
|
||||||
@@ -425,28 +425,28 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
|
|||||||
AstNode *align; \
|
AstNode *align; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(UnionType, "union type", struct { \
|
AST_NODE_KIND(UnionType, "union type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
Array<AstNode *> fields; \
|
Array<AstNode *> fields; \
|
||||||
isize field_count; \
|
isize field_count; \
|
||||||
Array<AstNode *> variants; \
|
Array<AstNode *> variants; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(RawUnionType, "raw union type", struct { \
|
AST_NODE_KIND(RawUnionType, "raw union type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
Array<AstNode *> fields; \
|
Array<AstNode *> fields; \
|
||||||
isize field_count; \
|
isize field_count; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(EnumType, "enum type", struct { \
|
AST_NODE_KIND(EnumType, "enum type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
AstNode *base_type; \
|
AstNode * base_type; \
|
||||||
Array<AstNode *> fields; /* FieldValue */ \
|
Array<AstNode *> fields; /* FieldValue */ \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(BitFieldType, "bit field type", struct { \
|
AST_NODE_KIND(BitFieldType, "bit field type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
Array<AstNode *> fields; /* FieldValue with : */ \
|
Array<AstNode *> fields; /* FieldValue with : */ \
|
||||||
AstNode *align; \
|
AstNode * align; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(MapType, "map type", struct { \
|
AST_NODE_KIND(MapType, "map type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
AstNode *count; \
|
AstNode *count; \
|
||||||
AstNode *key; \
|
AstNode *key; \
|
||||||
AstNode *value; \
|
AstNode *value; \
|
||||||
@@ -793,13 +793,34 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AstNode_BadDecl: break;
|
case AstNode_BadDecl: break;
|
||||||
case AstNode_ForeignLibrarySpec:
|
case AstNode_ProcDecl:
|
||||||
n->ForeignLibrarySpec.cond = clone_ast_node(a, n->ForeignLibrarySpec.cond);
|
n->ProcDecl.name = clone_ast_node(a, n->ProcDecl.name);
|
||||||
|
n->ProcDecl.type = clone_ast_node(a, n->ProcDecl.type);
|
||||||
|
n->ProcDecl.body = clone_ast_node(a, n->ProcDecl.body);
|
||||||
|
// TODO(bill): Clone the comment group too?
|
||||||
|
break;
|
||||||
|
case AstNode_ForeignBlockDecl:
|
||||||
|
n->ForeignBlockDecl.foreign_library = clone_ast_node(a, n->ForeignBlockDecl.foreign_library);
|
||||||
|
n->ForeignBlockDecl.decls = clone_ast_node_array(a, n->ForeignBlockDecl.decls);
|
||||||
break;
|
break;
|
||||||
case AstNode_Label:
|
case AstNode_Label:
|
||||||
n->Label.name = clone_ast_node(a, n->Label.name);
|
n->Label.name = clone_ast_node(a, n->Label.name);
|
||||||
break;
|
break;
|
||||||
|
case AstNode_GenDecl:
|
||||||
|
n->GenDecl.specs = clone_ast_node_array(a, n->GenDecl.specs);
|
||||||
|
break;
|
||||||
|
case AstNode_ValueSpec:
|
||||||
|
n->ValueSpec.names = clone_ast_node_array(a, n->ValueSpec.names);
|
||||||
|
n->ValueSpec.type = clone_ast_node(a, n->ValueSpec.type);
|
||||||
|
n->ValueSpec.values = clone_ast_node_array(a, n->ValueSpec.values);
|
||||||
|
break;
|
||||||
|
case AstNode_TypeSpec:
|
||||||
|
n->TypeSpec.name = clone_ast_node(a, n->TypeSpec.name);
|
||||||
|
n->TypeSpec.type = clone_ast_node(a, n->TypeSpec.type);
|
||||||
|
break;
|
||||||
|
case AstNode_ForeignLibrarySpec:
|
||||||
|
n->ForeignLibrarySpec.cond = clone_ast_node(a, n->ForeignLibrarySpec.cond);
|
||||||
|
break;
|
||||||
|
|
||||||
case AstNode_Field:
|
case AstNode_Field:
|
||||||
n->Field.names = clone_ast_node_array(a, n->Field.names);
|
n->Field.names = clone_ast_node_array(a, n->Field.names);
|
||||||
@@ -816,6 +837,8 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
|||||||
case AstNode_HelperType:
|
case AstNode_HelperType:
|
||||||
break;
|
break;
|
||||||
case AstNode_ProcType:
|
case AstNode_ProcType:
|
||||||
|
n->ProcType.params = clone_ast_node(a, n->ProcType.params);
|
||||||
|
n->ProcType.results = clone_ast_node(a, n->ProcType.results);
|
||||||
break;
|
break;
|
||||||
case AstNode_PointerType:
|
case AstNode_PointerType:
|
||||||
n->PointerType.type = clone_ast_node(a, n->PointerType.type);
|
n->PointerType.type = clone_ast_node(a, n->PointerType.type);
|
||||||
@@ -836,6 +859,7 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
|||||||
break;
|
break;
|
||||||
case AstNode_StructType:
|
case AstNode_StructType:
|
||||||
n->StructType.fields = clone_ast_node_array(a, n->StructType.fields);
|
n->StructType.fields = clone_ast_node_array(a, n->StructType.fields);
|
||||||
|
n->StructType.align = clone_ast_node(a, n->StructType.align);
|
||||||
break;
|
break;
|
||||||
case AstNode_UnionType:
|
case AstNode_UnionType:
|
||||||
n->UnionType.fields = clone_ast_node_array(a, n->UnionType.fields);
|
n->UnionType.fields = clone_ast_node_array(a, n->UnionType.fields);
|
||||||
@@ -3393,10 +3417,10 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
|
|||||||
syntax_error(f->curr_token, "Default parameters can only be applied to single values");
|
syntax_error(f->curr_token, "Default parameters can only be applied to single values");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parse_expect_field_separator(f, type);
|
||||||
AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
|
AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
|
||||||
array_add(¶ms, param);
|
array_add(¶ms, param);
|
||||||
|
|
||||||
parse_expect_field_separator(f, type);
|
|
||||||
|
|
||||||
while (f->curr_token.kind != follow &&
|
while (f->curr_token.kind != follow &&
|
||||||
f->curr_token.kind != Token_EOF) {
|
f->curr_token.kind != Token_EOF) {
|
||||||
@@ -3429,10 +3453,11 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
|
|||||||
syntax_error(f->curr_token, "Default parameters can only be applied to single values");
|
syntax_error(f->curr_token, "Default parameters can only be applied to single values");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ok = parse_expect_field_separator(f, param);
|
||||||
AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
|
AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
|
||||||
array_add(¶ms, param);
|
array_add(¶ms, param);
|
||||||
|
|
||||||
if (!parse_expect_field_separator(f, param)) {
|
if (!ok) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user