123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- import (
- win32 "sys/windows.odin";
- "fmt.odin";
- "os.odin";
- "mem.odin";
- )
- const (
- CANVAS_WIDTH = 128;
- CANVAS_HEIGHT = 128;
- CANVAS_SCALE = 3;
- FRAME_TIME = 1.0/30.0;
- WINDOW_TITLE = "Punity\x00";
- )
- const _ = compile_assert(CANVAS_WIDTH % 16 == 0);
- const (
- WINDOW_WIDTH = CANVAS_WIDTH * CANVAS_SCALE;
- WINDOW_HEIGHT = CANVAS_HEIGHT * CANVAS_SCALE;
- )
- const (
- STACK_CAPACITY = 1<<20;
- STORAGE_CAPACITY = 1<<20;
- DRAW_LIST_RESERVE = 128;
- MAX_KEYS = 256;
- )
- type Core struct {
- stack: ^Bank,
- storage: ^Bank,
- running: bool,
- key_modifiers: u32,
- key_states: [MAX_KEYS]u8,
- key_deltas: [MAX_KEYS]u8,
- perf_frame,
- perf_frame_inner,
- perf_step,
- perf_audio,
- perf_blit,
- perf_blit_cvt,
- perf_blit_gdi: Perf_Span,
- frame: i64,
- canvas: Canvas,
- draw_list: ^Draw_List,
- }
- type Perf_Span struct {
- stamp: f64,
- delta: f32,
- }
- type Bank struct {
- memory: []u8,
- cursor: int,
- }
- type Bank_State struct {
- state: Bank,
- bank: ^Bank,
- }
- type Color raw_union {
- using channels: struct{a, b, g, r: u8},
- rgba: u32,
- }
- type Palette struct {
- colors: [256]Color,
- colors_count: u8,
- }
- 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,
- }
- type Bitmap struct {
- pixels: []u8,
- width: int,
- height: int,
- }
- type Font struct {
- using bitmap: Bitmap,
- char_width: int,
- char_height: int,
- }
- type Canvas struct {
- using bitmap: ^Bitmap,
- palette: Palette,
- translate_x: int,
- translate_y: int,
- clip: Rect,
- font: ^Font,
- }
- type DrawFlag enum {
- NONE = 0,
- FLIP_H = 1<<0,
- FLIP_V = 1<<1,
- MASK = 1<<2,
- }
- type Draw_Item struct {}
- type Draw_List struct {
- items: []Draw_Item,
- }
- type Key enum {
- ModShift = 0x0001,
- ModControl = 0x0002,
- ModAlt = 0x0004,
- ModSuper = 0x0008,
- Unknown =-1,
- Invalid =-2,
- 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,
- F4 = 0x73,
- F5 = 0x74,
- F6 = 0x75,
- F7 = 0x76,
- F8 = 0x77,
- F9 = 0x78,
- F10 = 0x79,
- F11 = 0x7A,
- F12 = 0x7B,
- F13 = 0x7C,
- F14 = 0x7D,
- F15 = 0x7E,
- F16 = 0x7F,
- F17 = 0x80,
- F18 = 0x81,
- F19 = 0x82,
- F20 = 0x83,
- F21 = 0x84,
- F22 = 0x85,
- F23 = 0x86,
- F24 = 0x87,
- 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, /* = */
- A = 65,
- B = 66,
- C = 67,
- D = 68,
- E = 69,
- F = 70,
- G = 71,
- H = 72,
- I = 73,
- J = 74,
- K = 75,
- L = 76,
- M = 77,
- N = 78,
- O = 79,
- P = 80,
- Q = 81,
- R = 82,
- S = 83,
- T = 84,
- U = 85,
- V = 86,
- W = 87,
- X = 88,
- Y = 89,
- Z = 90,
- LeftBracket = 91, /* [ */
- Backslash = 92, /* \ */
- RightBracket = 93, /* ] */
- GraveAccent = 96, /* ` */
- };
- proc key_down(k: Key) -> bool {
- return _core.key_states[k] != 0;
- }
- proc key_pressed(k: Key) -> bool {
- return (_core.key_deltas[k] != 0) && key_down(k);
- }
- let win32_perf_count_freq = win32.get_query_performance_frequency();
- proc time_now() -> f64 {
- assert(win32_perf_count_freq != 0);
- var counter: i64;
- win32.query_performance_counter(&counter);
- return f64(counter) / f64(win32_perf_count_freq);
- }
- var _core: Core;
- proc run(user_init, user_step: proc(c: ^Core)) {
- using win32;
- _core.running = true;
- 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(KeyCode.Shift) {
- mods |= u32(Key.ModShift);
- }
- if is_key_down(KeyCode.Control) {
- mods |= u32(Key.ModControl);
- }
- if is_key_down(KeyCode.Menu) {
- mods |= u32(Key.ModAlt);
- }
- if is_key_down(KeyCode.Lwin) || is_key_down(KeyCode.Rwin) {
- mods |= u32(Key.ModSuper);
- }
- return mods;
- }
- match msg {
- case WM_KEYDOWN:
- _core.key_modifiers = win32_app_key_mods();
- if wparam < MAX_KEYS {
- _core.key_states[wparam] = 1;
- _core.key_deltas[wparam] = 1;
- }
- return 0;
- case WM_KEYUP:
- _core.key_modifiers = win32_app_key_mods();
- if wparam < MAX_KEYS {
- _core.key_states[wparam] = 0;
- _core.key_deltas[wparam] = 1;
- }
- return 0;
- case WM_CLOSE:
- post_quit_message(0);
- _core.running = false;
- return 0;
- }
- return def_window_proc_a(hwnd, msg, wparam, lparam);
- }
- 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 = Hinstance(get_module_handle_a(nil)),
- wnd_proc = win32_proc,
- // wnd_proc = DefWindowProcA,
- background = Hbrush(get_stock_object(BLACK_BRUSH)),
- };
- if register_class_ex_a(&window_class) == 0 {
- fmt.fprintln(os.stderr, "register_class_ex_a failed");
- return;
- }
- var screen_width = get_system_metrics(SM_CXSCREEN);
- var screen_height = get_system_metrics(SM_CYSCREEN);
- 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;
- var style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
- assert(adjust_window_rect(&rc, style, 0) != 0);
- var wt = WINDOW_TITLE;
- 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, "create_window_ex_a failed");
- return;
- }
- var window_bmi: BitmapInfo;
- window_bmi.size = size_of(BitmapInfoHeader);
- 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);
- show_window(win32_window, SW_SHOW);
- var window_buffer = make([]u32, CANVAS_WIDTH * CANVAS_HEIGHT);
- defer free(window_buffer);
- 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;
- )
- var message: Msg;
- for _core.running {
- curr_time = time_now();
- dt = curr_time - prev_time;
- prev_time = curr_time;
- total_time += dt;
- offset_x += 1;
- offset_y += 2;
- {
- 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 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(_core.key_deltas));
- for peek_message_a(&message, nil, 0, 0, PM_REMOVE) != 0 {
- if message.message == WM_QUIT {
- _core.running = false;
- }
- translate_message(&message);
- dispatch_message_a(&message);
- }
- user_step(&_core);
- 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);
- {
- var delta = time_now() - prev_time;
- var ms = i32((FRAME_TIME - delta) * 1000);
- if ms > 0 {
- win32.sleep(ms);
- }
- }
- _core.frame++;
- }
- }
- proc main() {
- proc user_init(c: ^Core) {
- }
- proc user_step(c: ^Core) {
- }
- run(user_init, user_step);
- }
|