Update old demos

This commit is contained in:
Ginger Bill
2017-06-21 21:20:26 +01:00
parent 264ca00db7
commit 53075e2570
10 changed files with 428 additions and 432 deletions
+2 -1
View File
@@ -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
View File
@@ -1,38 +1,37 @@
#import win32 "sys/windows.odin" when ODIN_OS == "windows";
#import wgl "sys/wgl.odin" when ODIN_OS == "windows";
#import "fmt.odin";
#import "math.odin";
#import "os.odin";
#import gl "opengl.odin";
import win32 "sys/windows.odin" when ODIN_OS == "windows";
import wgl "sys/wgl.odin" when ODIN_OS == "windows";
import "fmt.odin";
import "math.odin";
import "os.odin";
import gl "opengl.odin";
TWO_HEARTS :: '💕';
const TWO_HEARTS = '💕';
win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
time_now :: proc() -> f64 {
var win32_perf_count_freq = win32.get_query_performance_frequency();
proc time_now() -> f64 {
assert(win32_perf_count_freq != 0);
counter: i64;
win32.QueryPerformanceCounter(^counter);
result := cast(f64)counter / cast(f64)win32_perf_count_freq;
return result;
var counter: i64;
win32.query_performance_counter(&counter);
return f64(counter) / f64(win32_perf_count_freq);
}
win32_print_last_error :: proc() {
err_code := cast(int)win32.GetLastError();
proc win32_print_last_error() {
var err_code = win32.get_last_error();
if err_code != 0 {
fmt.println("GetLastError: %", err_code);
fmt.println("get_last_error: ", err_code);
}
}
// Yuk!
to_c_string :: proc(s: string) -> []u8 {
c_str := make([]u8, len(s)+1);
copy(c_str, cast([]byte)s);
proc to_c_string(s: string) -> []u8 {
var c_str = make([]u8, len(s)+1);
copy(c_str, []u8(s));
c_str[len(s)] = 0;
return c_str;
}
Window :: struct {
type Window struct {
width, height: int,
wc: win32.WndClassExA,
dc: win32.Hdc,
@@ -41,52 +40,52 @@ Window :: struct {
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;
w: Window;
var w: Window;
w.width, w.height = msg, height;
class_name := "Win32-Odin-Window\x00";
c_class_name := ^class_name[0];
var class_name = "Win32-Odin-Window\x00";
var c_class_name = &class_name[0];
if title[len(title)-1] != 0 {
w.c_title = to_c_string(title);
} 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{
size = size_of(WndClassExA),
style = CS_VREDRAW | CS_HREDRAW,
instance = cast(Hinstance)instance,
instance = Hinstance(instance),
class_name = c_class_name,
wnd_proc = window_proc,
};
if RegisterClassExA(^w.wc) == 0 {
if register_class_ex_a(&w.wc) == 0 {
win32_print_last_error();
return w, false;
}
w.hwnd = CreateWindowExA(0,
c_class_name, ^w.c_title[0],
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
cast(i32)w.width, cast(i32)w.height,
nil, nil, instance, nil);
w.hwnd = create_window_ex_a(0,
c_class_name, &w.c_title[0],
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
i32(w.width), i32(w.height),
nil, nil, instance, nil);
if w.hwnd == nil {
win32_print_last_error();
return w, false;
}
w.dc = GetDC(w.hwnd);
w.dc = get_dc(w.hwnd);
{
pfd := PIXELFORMATDESCRIPTOR{
size = size_of(PIXELFORMATDESCRIPTOR),
var pfd = PixelFormatDescriptor{
size = size_of(PixelFormatDescriptor),
version = 1,
flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
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,
};
SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil);
w.opengl_context = wgl.CreateContext(w.dc);
wgl.MakeCurrent(w.dc, w.opengl_context);
set_pixel_format(w.dc, choose_pixel_format(w.dc, &pfd), nil);
w.opengl_context = wgl.create_context(w.dc);
wgl.make_current(w.dc, w.opengl_context);
attribs := [8]i32{
var 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
};
wgl_str := "wglCreateContextAttribsARB\x00";
wglCreateContextAttribsARB := cast(wgl.Create_Context_Attribs_ARB_Type)wgl.GetProcAddress(^wgl_str[0]);
w.rc = wglCreateContextAttribsARB(w.dc, nil, ^attribs[0]);
wgl.MakeCurrent(w.dc, w.rc);
SwapBuffers(w.dc);
var wgl_str = "wglCreateContextAttribsARB\x00";
var wglCreateContextAttribsARB = wgl.CreateContextAttribsARBType(wgl.get_proc_address(&wgl_str[0]));
w.rc = wglCreateContextAttribsARB(w.dc, nil, &attribs[0]);
wgl.make_current(w.dc, w.rc);
swap_buffers(w.dc);
}
return w, true;
}
destroy_window :: proc(w: ^Window) {
proc destroy_window(w: ^Window) {
free(w.c_title);
}
display_window :: proc(w: ^Window) {
win32.SwapBuffers(w.dc);
proc display_window(w: ^Window) {
win32.swap_buffers(w.dc);
}
run :: proc() {
using win32;
proc run() {
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 {
os.exit(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 {
return;
}
defer destroy_window(^window);
defer destroy_window(&window);
gl.init();
using win32;
prev_time := time_now();
running := true;
var prev_time = time_now();
var running = true;
pos := Vec2{100, 100};
var pos = Vec2{100, 100};
for running {
curr_time := time_now();
dt := cast(f32)(curr_time - prev_time);
var curr_time = time_now();
var dt = f32(curr_time - prev_time);
prev_time = curr_time;
msg: Msg;
for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 {
var msg: Msg;
for peek_message_a(&msg, nil, 0, 0, PM_REMOVE) > 0 {
if msg.message == WM_QUIT {
running = false;
}
TranslateMessage(^msg);
DispatchMessageA(^msg);
translate_message(&msg);
dispatch_message_a(&msg);
}
if is_key_down(Key_Code.ESCAPE) {
if is_key_down(KeyCode.Escape) {
running = false;
}
{
SPEED :: 500;
v: Vec2;
const SPEED = 500;
var 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(KeyCode.Right) { v[0] += 1; }
if is_key_down(KeyCode.Left) { v[0] -= 1; }
if is_key_down(KeyCode.Up) { v[1] += 1; }
if is_key_down(KeyCode.Down) { v[1] -= 1; }
v = norm(v);
@@ -190,10 +190,10 @@ run :: proc() {
gl.Clear(gl.COLOR_BUFFER_BIT);
gl.LoadIdentity();
gl.Ortho(0, cast(f64)window.width,
0, cast(f64)window.height, 0, 1);
gl.Ortho(0, f64(window.width),
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);
defer gl.End();
@@ -208,15 +208,15 @@ run :: proc() {
draw_rect(pos.x, pos.y, 50, 50);
display_window(^window);
ms_to_sleep := cast(i32)(16 - 1000*dt);
display_window(&window);
var ms_to_sleep = i32(16 - 1000*dt);
if ms_to_sleep > 0 {
win32.Sleep(ms_to_sleep);
win32.sleep(ms_to_sleep);
}
}
}
main :: proc() {
proc main() {
run();
}
+62 -58
View File
@@ -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;
INVALID_SOCKET :: ~(cast(SOCKET)0);
type SOCKET uint;
const INVALID_SOCKET = ~SOCKET(0);
AF :: enum i32 {
type AF enum i32 {
UNSPEC = 0, // unspecified
UNIX = 1, // local to host (pipes, portals)
INET = 2, // internetwork: UDP, TCP, etc.
@@ -37,19 +37,22 @@ AF :: enum i32 {
MAX = 26,
};
SOCK_STREAM :: 1;
SOCKET_ERROR :: -1;
IPPROTO_TCP :: 6;
AI_PASSIVE :: 0x0020;
SOMAXCONN :: 128;
const (
SOCK_STREAM = 1;
SOCKET_ERROR = -1;
IPPROTO_TCP = 6;
AI_PASSIVE = 0x0020;
SOMAXCONN = 128;
)
const (
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;
WSADATA :: struct #ordered {
const WSADESCRIPTION_LEN = 256;
const WSASYS_STATUS_LEN = 128;
type WSADATA struct #ordered {
version: i16,
high_version: i16,
@@ -57,12 +60,12 @@ WSADATA :: struct #ordered {
// 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,
vendor_info: ^u8,
description: [WSADESCRIPTION_LEN+1]u8,
system_status: [WSASYS_STATUS_LEN+1]u8,
}
addrinfo :: struct #ordered {
type addrinfo struct #ordered {
flags: i32,
family: i32,
socktype: i32,
@@ -73,52 +76,53 @@ addrinfo :: struct #ordered {
next: ^addrinfo,
}
sockaddr :: struct #ordered {
type sockaddr struct #ordered {
family: u16,
data: [14]byte,
data: [14]u8,
}
WSAStartup :: proc(version_requested: i16, data: ^WSADATA) -> i32 #foreign ws2;
WSACleanup :: proc() -> i32 #foreign ws2;
getaddrinfo :: proc(node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32 #foreign ws2;
freeaddrinfo :: proc(ai: ^addrinfo) #foreign ws2;
socket :: proc(af, type_, protocol: i32) -> SOCKET #foreign ws2;
closesocket :: proc(s: SOCKET) -> i32 #foreign ws2;
bind :: proc(s: SOCKET, name: ^sockaddr, name_len: i32) -> i32 #foreign ws2;
listen :: proc(s: SOCKET, back_log: i32) -> i32 #foreign ws2;
accept :: proc(s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET #foreign ws2;
recv :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32 #foreign ws2;
send :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32 #foreign ws2;
shutdown :: proc(s: SOCKET, how: i32) -> i32 #foreign ws2;
WSAGetLastError :: proc() -> i32 #foreign ws2;
to_c_string :: proc(s: string) -> ^byte {
c_str := new_slice(byte, s.count+1);
assert(c_str.data != nil);
copy(c_str, cast([]byte)s);
c_str[s.count] = 0;
return c_str.data;
foreign ws2 {
proc WSAStartup (version_requested: i16, data: ^WSADATA) -> i32;
proc WSACleanup () -> i32;
proc getaddrinfo (node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32;
proc freeaddrinfo (ai: ^addrinfo);
proc socket (af, type_, protocol: i32) -> SOCKET;
proc closesocket (s: SOCKET) -> i32;
proc bind (s: SOCKET, name: ^sockaddr, name_len: i32) -> i32;
proc listen (s: SOCKET, back_log: i32) -> i32;
proc accept (s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET;
proc recv (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
proc send (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
proc shutdown (s: SOCKET, how: i32) -> i32;
proc WSAGetLastError() -> i32;
}
proc to_c_string(s: string) -> ^u8 {
var c_str = make([]u8, len(s)+1);
copy(c_str, []u8(s));
c_str[len(s)] = 0;
return &c_str[0];
}
run :: proc() {
wsa: WSADATA;
res: ^addrinfo = nil;
hints: addrinfo;
s, client: SOCKET;
proc run() {
var (
wsa: WSADATA;
res: ^addrinfo = nil;
hints: addrinfo;
s, client: SOCKET;
)
if WSAStartup(2 | (2 << 8), ^wsa) != 0 {
if WSAStartup(2 | (2 << 8), &wsa) != 0 {
fmt.println("WSAStartup failed: ", WSAGetLastError());
return;
}
defer WSACleanup();
hints.family = cast(i32)AF.INET;
hints.family = i32(AF.INET);
hints.socktype = SOCK_STREAM;
hints.protocol = IPPROTO_TCP;
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());
return;
}
@@ -131,7 +135,7 @@ run :: proc() {
}
defer closesocket(s);
bind(s, res.addr, cast(i32)res.addrlen);
bind(s, res.addr, i32(res.addrlen));
listen(s, SOMAXCONN);
client = accept(s, nil, 0);
@@ -141,7 +145,7 @@ run :: proc() {
}
defer closesocket(client);
html :=
var html =
`HTTP/1.1 200 OK
Connection: close
Content-type: text/html
@@ -156,12 +160,12 @@ Content-type: text/html
</html>
`;
buf: [1024]byte;
var buf: [1024]u8;
for {
bytes := recv(client, ^buf[0], cast(i32)buf.count, 0);
var bytes = recv(client, &buf[0], i32(len(buf)), 0);
if bytes > 0 {
// fmt.println(buf[:bytes] as string)
bytes_sent := send(client, html.data, cast(i32)(html.count-1), 0);
// fmt.println(string(buf[0..<bytes]))
var bytes_sent = send(client, &html[0], i32(len(html)-1), 0);
if bytes_sent == SOCKET_ERROR {
fmt.println("send failed: ", WSAGetLastError());
return;
+233 -224
View File
@@ -1,35 +1,42 @@
#import win32 "sys/windows.odin";
#import "fmt.odin";
#import "os.odin";
#import "mem.odin";
import (
win32 "sys/windows.odin";
"fmt.odin";
"os.odin";
"mem.odin";
)
CANVAS_WIDTH :: 128;
CANVAS_HEIGHT :: 128;
CANVAS_SCALE :: 3;
FRAME_TIME :: 1.0/30.0;
WINDOW_TITLE :: "Punity\x00";
const (
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);
const _ = compile_assert(CANVAS_WIDTH % 16 == 0);
WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE;
WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE;
const (
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;
STORAGE_CAPACITY :: 1<<20;
DRAW_LIST_RESERVE = 128;
DRAW_LIST_RESERVE :: 128;
MAX_KEYS = 256;
)
MAX_KEYS :: 256;
Core :: struct {
type Core struct {
stack: ^Bank,
storage: ^Bank,
running: bool,
key_modifiers: u32,
key_states: [MAX_KEYS]byte,
key_deltas: [MAX_KEYS]byte,
key_states: [MAX_KEYS]u8,
key_deltas: [MAX_KEYS]u8,
perf_frame,
perf_frame_inner,
@@ -45,52 +52,52 @@ Core :: struct {
draw_list: ^Draw_List,
}
Perf_Span :: struct {
type Perf_Span struct {
stamp: f64,
delta: f32,
}
Bank :: struct {
memory: []byte,
type Bank struct {
memory: []u8,
cursor: int,
}
Bank_State :: struct {
type Bank_State struct {
state: Bank,
bank: ^Bank,
}
Color :: raw_union {
using channels: struct{a, b, g, r: byte},
type Color raw_union {
using channels: struct{a, b, g, r: u8},
rgba: u32,
}
Palette :: struct {
type Palette struct {
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 pos: struct {left, top, right, bottom: int},
e: [4]int,
}
Bitmap :: struct {
pixels: []byte,
type Bitmap struct {
pixels: []u8,
width: int,
height: int,
}
Font :: struct {
type Font struct {
using bitmap: Bitmap,
char_width: int,
char_height: int,
}
Canvas :: struct {
type Canvas struct {
using bitmap: ^Bitmap,
palette: Palette,
translate_x: int,
@@ -99,89 +106,92 @@ Canvas :: struct {
font: ^Font,
}
DrawFlag :: enum {
type DrawFlag enum {
NONE = 0,
FLIP_H = 1<<0,
FLIP_V = 1<<1,
MASK = 1<<2,
}
Draw_Item :: struct {}
Draw_List :: struct {
type Draw_Item struct {}
type Draw_List struct {
items: []Draw_Item,
}
Key :: enum {
MOD_SHIFT = 0x0001,
MOD_CONTROL = 0x0002,
MOD_ALT = 0x0004,
MOD_SUPER = 0x0008,
type Key enum {
ModShift = 0x0001,
ModControl = 0x0002,
ModAlt = 0x0004,
ModSuper = 0x0008,
UNKNOWN =-1,
INVALID =-2,
LBUTTON = 1,
RBUTTON = 2,
CANCEL = 3,
MBUTTON = 4,
Unknown =-1,
Invalid =-2,
BACK = 8,
TAB = 9,
CLEAR = 12,
RETURN = 13,
SHIFT = 16,
CONTROL = 17,
MENU = 18,
PAUSE = 19,
CAPITAL = 20,
KANA = 0x15,
HANGEUL = 0x15,
HANGUL = 0x15,
JUNJA = 0x17,
FINAL = 0x18,
HANJA = 0x19,
KANJI = 0x19,
ESCAPE = 0x1B,
CONVERT = 0x1C,
NONCONVERT = 0x1D,
ACCEPT = 0x1E,
MODECHANGE = 0x1F,
SPACE = 32,
PRIOR = 33,
NEXT = 34,
END = 35,
HOME = 36,
LEFT = 37,
UP = 38,
RIGHT = 39,
DOWN = 40,
SELECT = 41,
PRINT = 42,
EXEC = 43,
SNAPSHOT = 44,
INSERT = 45,
DELETE = 46,
HELP = 47,
LWIN = 0x5B,
RWIN = 0x5C,
APPS = 0x5D,
SLEEP = 0x5F,
NUMPAD0 = 0x60,
NUMPAD1 = 0x61,
NUMPAD2 = 0x62,
NUMPAD3 = 0x63,
NUMPAD4 = 0x64,
NUMPAD5 = 0x65,
NUMPAD6 = 0x66,
NUMPAD7 = 0x67,
NUMPAD8 = 0x68,
NUMPAD9 = 0x69,
MULTIPLY = 0x6A,
ADD = 0x6B,
SEPARATOR = 0x6C,
SUBTRACT = 0x6D,
DECIMAL = 0x6E,
DIVIDE = 0x6F,
Lbutton = 1,
Rbutton = 2,
Cancel = 3,
Mbutton = 4,
Back = 8,
Tab = 9,
Clear = 12,
Return = 13,
Shift = 16,
Control = 17,
Menu = 18,
Pause = 19,
Capital = 20,
Kana = 0x15,
Hangeul = 0x15,
Hangul = 0x15,
Junja = 0x17,
Final = 0x18,
Hanja = 0x19,
Kanji = 0x19,
Escape = 0x1B,
Convert = 0x1C,
NonConvert = 0x1D,
Accept = 0x1E,
ModeChange = 0x1F,
Space = 32,
Prior = 33,
Next = 34,
End = 35,
Home = 36,
Left = 37,
Up = 38,
Right = 39,
Down = 40,
Select = 41,
Print = 42,
Exec = 43,
Snapshot = 44,
Insert = 45,
Delete = 46,
Help = 47,
Lwin = 0x5B,
Rwin = 0x5C,
Apps = 0x5D,
Sleep = 0x5F,
Numpad0 = 0x60,
Numpad1 = 0x61,
Numpad2 = 0x62,
Numpad3 = 0x63,
Numpad4 = 0x64,
Numpad5 = 0x65,
Numpad6 = 0x66,
Numpad7 = 0x67,
Numpad8 = 0x68,
Numpad9 = 0x69,
Multiply = 0x6A,
Add = 0x6B,
Separator = 0x6C,
Subtract = 0x6D,
Decimal = 0x6E,
Divide = 0x6F,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
@@ -206,32 +216,33 @@ Key :: enum {
F22 = 0x85,
F23 = 0x86,
F24 = 0x87,
NUMLOCK = 0x90,
SCROLL = 0x91,
LSHIFT = 0xA0,
RSHIFT = 0xA1,
LCONTROL = 0xA2,
RCONTROL = 0xA3,
LMENU = 0xA4,
RMENU = 0xA5,
Numlock = 0x90,
Scroll = 0x91,
Lshift = 0xA0,
Rshift = 0xA1,
Lcontrol = 0xA2,
Rcontrol = 0xA3,
Lmenu = 0xA4,
Rmenu = 0xA5,
APOSTROPHE = 39, /* ' */
COMMA = 44, /* , */
MINUS = 45, /* - */
PERIOD = 46, /* . */
SLASH = 47, /* / */
NUM0 = 48,
NUM1 = 49,
NUM2 = 50,
NUM3 = 51,
NUM4 = 52,
NUM5 = 53,
NUM6 = 54,
NUM7 = 55,
NUM8 = 56,
NUM9 = 57,
SEMICOLON = 59, /* ; */
EQUAL = 61, /* = */
Apostrophe = 39, /* ' */
Comma = 44, /* , */
Minus = 45, /* - */
Period = 46, /* . */
Slash = 47, /* / */
Num0 = 48,
Num1 = 49,
Num2 = 50,
Num3 = 51,
Num4 = 52,
Num5 = 53,
Num6 = 54,
Num7 = 55,
Num8 = 56,
Num9 = 57,
Semicolon = 59, /* ; */
Equal = 61, /* = */
A = 65,
B = 66,
C = 67,
@@ -258,56 +269,55 @@ Key :: enum {
X = 88,
Y = 89,
Z = 90,
LEFT_BRACKET = 91, /* [ */
BACKSLASH = 92, /* \ */
RIGHT_BRACKET = 93, /* ] */
GRAVE_ACCENT = 96, /* ` */
LeftBracket = 91, /* [ */
Backslash = 92, /* \ */
RightBracket = 93, /* ] */
GraveAccent = 96, /* ` */
};
key_down :: proc(k: Key) -> bool {
proc key_down(k: Key) -> bool {
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);
}
win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
time_now :: proc() -> f64 {
let win32_perf_count_freq = win32.get_query_performance_frequency();
proc time_now() -> f64 {
assert(win32_perf_count_freq != 0);
counter: i64;
win32.QueryPerformanceCounter(^counter);
result := cast(f64)counter / cast(f64)win32_perf_count_freq;
return result;
var counter: i64;
win32.query_performance_counter(&counter);
return f64(counter) / f64(win32_perf_count_freq);
}
_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;
_core.running = true;
win32_proc :: proc(hwnd: win32.HWND, msg: u32, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT #no_inline #cc_c {
win32_app_key_mods :: proc() -> u32 {
mods: u32 = 0;
proc win32_proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline #cc_c {
proc win32_app_key_mods() -> u32 {
var mods: u32 = 0;
if is_key_down(Key_Code.SHIFT) {
mods |= cast(u32)Key.MOD_SHIFT;
if is_key_down(KeyCode.Shift) {
mods |= u32(Key.ModShift);
}
if is_key_down(Key_Code.CONTROL) {
mods |= cast(u32)Key.MOD_CONTROL;
if is_key_down(KeyCode.Control) {
mods |= u32(Key.ModControl);
}
if is_key_down(Key_Code.MENU) {
mods |= cast(u32)Key.MOD_ALT;
if is_key_down(KeyCode.Menu) {
mods |= u32(Key.ModAlt);
}
if is_key_down(Key_Code.LWIN) || is_key_down(Key_Code.RWIN) {
mods |= cast(u32)Key.MOD_SUPER;
if is_key_down(KeyCode.Lwin) || is_key_down(KeyCode.Rwin) {
mods |= u32(Key.ModSuper);
}
return mods;
@@ -331,61 +341,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
return 0;
case WM_CLOSE:
PostQuitMessage(0);
post_quit_message(0);
_core.running = false;
return 0;
}
return DefWindowProcA(hwnd, msg, wparam, lparam);
return def_window_proc_a(hwnd, msg, wparam, lparam);
}
window_class := WNDCLASSEXA{
class_name = (cast(string)"Punity\x00").data, // C-style string
size = size_of(WNDCLASSEXA),
var class_name = "Punity\x00";
var window_class = WndClassExA{
class_name = &class_name[0],
size = size_of(WndClassExA),
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 = DefWindowProcA,
background = cast(HBRUSH)GetStockObject(BLACK_BRUSH),
background = Hbrush(get_stock_object(BLACK_BRUSH)),
};
if RegisterClassExA(^window_class) == 0 {
fmt.fprintln(os.stderr, "RegisterClassExA failed");
if register_class_ex_a(&window_class) == 0 {
fmt.fprintln(os.stderr, "register_class_ex_a failed");
return;
}
screen_width := GetSystemMetrics(SM_CXSCREEN);
screen_height := GetSystemMetrics(SM_CYSCREEN);
var screen_width = get_system_metrics(SM_CXSCREEN);
var screen_height = get_system_metrics(SM_CYSCREEN);
rc: RECT;
var 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);
var style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
assert(adjust_window_rect(&rc, style, 0) != 0);
wt := WINDOW_TITLE;
var wt = WINDOW_TITLE;
win32_window := CreateWindowExA(0,
window_class.class_name,
wt.data,
style,
rc.left, rc.top,
rc.right-rc.left, rc.bottom-rc.top,
nil, nil, window_class.instance,
nil);
var win32_window = create_window_ex_a(0,
window_class.class_name,
&wt[0],
style,
rc.left, rc.top,
rc.right-rc.left, rc.bottom-rc.top,
nil, nil, window_class.instance,
nil);
if win32_window == nil {
fmt.fprintln(os.stderr, "CreateWindowExA failed");
fmt.fprintln(os.stderr, "create_window_ex_a failed");
return;
}
window_bmi: BITMAPINFO;
window_bmi.size = size_of(BITMAPINFOHEADER);
var window_bmi: BitmapInfo;
window_bmi.size = size_of(BitmapInfoHeader);
window_bmi.width = CANVAS_WIDTH;
window_bmi.height = CANVAS_HEIGHT;
window_bmi.planes = 1;
@@ -393,27 +404,27 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
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);
for i := 0; i < window_buffer.count; i += 1 {
for _, i in window_buffer {
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;
prev_time := time_now();
curr_time := time_now();
total_time : f64 = 0;
offset_x := 0;
offset_y := 0;
message: MSG;
var message: Msg;
for _core.running {
curr_time = time_now();
dt = curr_time - prev_time;
@@ -424,64 +435,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
offset_y += 2;
{
data: [128]byte;
buf: fmt.Buffer;
buf.data = data[:];
fmt.bprintf(^buf, "Punity: %.4f ms\x00", dt*1000);
win32.SetWindowTextA(win32_window, ^buf[0]);
var buf: [128]u8;
var s = fmt.bprintf(buf[..], "Punity: %.4f ms\x00", dt*1000);
win32.set_window_text_a(win32_window, &s[0]);
}
for y := 0; y < CANVAS_HEIGHT; y += 1 {
for x := 0; x < CANVAS_WIDTH; x += 1 {
g := (x % 32) * 8;
b := (y % 32) * 8;
window_buffer[x + y*CANVAS_WIDTH] = cast(u32)(g << 8 | b);
for var y = 0; y < CANVAS_HEIGHT; y++ {
for var x = 0; x < CANVAS_WIDTH; x++ {
var g = (x % 32) * 8;
var b = (y % 32) * 8;
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 {
_core.running = false;
}
TranslateMessage(^message);
DispatchMessageA(^message);
translate_message(&message);
dispatch_message_a(&message);
}
user_step(^_core);
user_step(&_core);
dc := GetDC(win32_window);
StretchDIBits(dc,
0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
window_buffer.data,
^window_bmi,
DIB_RGB_COLORS,
SRCCOPY);
ReleaseDC(win32_window, dc);
var dc = get_dc(win32_window);
stretch_dibits(dc,
0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
&window_buffer[0],
&window_bmi,
DIB_RGB_COLORS,
SRCCOPY);
release_dc(win32_window, dc);
{
delta := time_now() - prev_time;
ms := cast(i32)((FRAME_TIME - delta) * 1000);
var delta = time_now() - prev_time;
var ms = i32((FRAME_TIME - delta) * 1000);
if ms > 0 {
win32.Sleep(ms);
win32.sleep(ms);
}
}
_core.frame += 1;
_core.frame++;
}
}
main :: proc() {
user_init :: proc(c: ^Core) {
proc main() {
proc user_init(c: ^Core) {
}
user_step :: proc(c: ^Core) {
proc user_step(c: ^Core) {
}
-5
View File
@@ -1,5 +0,0 @@
#import "fmt.odin" as fmt
thing :: proc() {
fmt.println("Sub Hello!")
}
-35
View File
@@ -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!")
}*/