diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index 2cecc00..98d9bbc 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -545,7 +545,7 @@ gen_ast(Ast *ast){ int i = 0; For(node->expr){ - genln("memcpy(&%Q.m%d, ", var_name, i); + genln("CORE_MemoryCopy(&%Q.m%d, ", var_name, i); if(!is_array(it->resolved_type)) gen("&"); gen("("); gen_expr(it); @@ -761,7 +761,7 @@ gen_ast(Ast *ast){ int i = 0; For(node->vars){ - gen("memcpy((void *)&%Q, (void *)&%Q.m%d, sizeof(%Q));", it->name, var_name, i++, it->name); + gen("CORE_MemoryCopy((void *)&%Q, (void *)&%Q.m%d, sizeof(%Q));", it->name, var_name, i++, it->name); } BREAK(); } @@ -785,7 +785,6 @@ compile_to_c_code(){ gen(R"==( #include #include -#include #define CORE_Assert(x) do{if(!(x))__debugbreak();}while(0) #define CORE_AssertMessage(x,...) CORE_Assert(x) #define CORE_BufferSize(x) (sizeof(x)/sizeof((x)[0])) @@ -793,6 +792,16 @@ typedef struct String{ uint8_t *str; int64_t len; }String; + +static void +CORE_MemoryCopy(void *dst, void *src, size_t size){ + uint8_t *d = (uint8_t*)dst; + uint8_t *s = (uint8_t*)src; + for(size_t i = 0; i < size; i++){ + d[i] = s[i]; + } +} + )=="); // Generate struct forward decls diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 6914ddf..98bedc8 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1016,7 +1016,7 @@ require_const_int(Ast_Expr *expr, Resolve_Flag flags){ if(!op.is_const) compiler_error(expr->pos, "Expected a const value"); - if(!is_int(op.type)) + if(!(is_int(op.type) || is_enum(op.type))) compiler_error(expr->pos, "Expected a constant integer got instead %Q", typestring(op.type)); return op; @@ -1491,7 +1491,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_ CASE(INDEX, Index){ Operand left = resolve_expr(node->expr, AST_CANT_BE_NULL , 0, field_access_scope); Operand index = resolve_expr(node->index, AST_CANT_BE_NULL, 0, 0); - if(!is_int(index.type)) + if(!(is_int(index.type) || is_enum(index.type))) compiler_error(node->pos, "Trying to index the array with invalid type, expected [Int] got instead %Q", typestring(index.type)); node->index_original_type = left.type; diff --git a/examples/using_multimedia.core b/examples/using_multimedia.core index a516882..4be041b 100644 --- a/examples/using_multimedia.core +++ b/examples/using_multimedia.core @@ -1,7 +1,6 @@ #import "Multimedia.core" WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int - mu := StartMultimedia(title = "Hello, people!") - - for UpdateMultimedia(&mu) + StartMultimedia(title = "Hello, people!") + for UpdateMultimedia() pass \ No newline at end of file diff --git a/meta_run.py b/meta_run.py index d93ddca..7de5e9d 100644 --- a/meta_run.py +++ b/meta_run.py @@ -3,7 +3,7 @@ import sys import os -files = ["core_compiler.cpp", "core_compiler.h", "core_globals.cpp", "core_lexing.cpp", "core_generated.cpp"] +files = ["core_compiler.cpp", "core_compiler.h", "core_globals.cpp", "core_lexing.cpp", "core_generated.cpp", "modules/win32_multimedia.core"] for file_to_modify in files: fd = open(file_to_modify, "r+") diff --git a/modules/Multimedia.core b/modules/Multimedia.core index f113f18..0d342f5 100644 --- a/modules/Multimedia.core +++ b/modules/Multimedia.core @@ -8,11 +8,13 @@ API and name inspired by one of Per Vognsen streams https://www.youtube.com/watch?v=NG_mUhc8LRw&list=PLU94OURih-CjrtFuazwZ5GYzTrupOMDL7&index=19 All of his channel is recommended watch for programmers. */ -Mu :: struct +Mu: MU +MU :: struct scrn: *U32 x : S64 y : S64 + key: [Key.Count]KeyState frame_count: U64 time: MuTime quit: Bool @@ -26,7 +28,18 @@ MuTime :: struct start : F64 frame_start: F64 +KeyState :: struct + is_down: Bool +Key :: enum + Nil + Up;Down;Left;Right;Escape;Control;Backspace;Alt;Shift;Tab + F1;F2;F3;F4;F5;F6;F7;F8;F9;F10 + F11;F12;A;B;C;D;E;F;G;H + I;J;K;L;M;N;O;P;Q;R + S;T;U;V;W;X;Y;Z;K0;K1 + K2;K3;K4;K5;K6;K7;K8;K9 + Count StartMultimedia :: W32.StartMultimedia UpdateMultimedia :: W32.UpdateMultimedia diff --git a/modules/USER32.core b/modules/USER32.core index 89506ec..29f6b76 100644 --- a/modules/USER32.core +++ b/modules/USER32.core @@ -24,9 +24,6 @@ AdjustWindowRectEx :: #foreign (lpRect: *RECT, dwStyle: DWORD, bMenu: BOOL, dwEx SetWindowPos :: #foreign (hWnd: HWND, hWndInsertAfter: HWND, X: int, Y: int, cx: int, cy: int, uFlags: UINT): BOOL GetClientRect :: #foreign (hWnd: HWND, lpRect: LPRECT): BOOL -WM_NULL :: 0x0000; WM_CREATE :: 0x0001; WM_DESTROY :: 0x0002; WM_MOVE :: 0x0003; WM_SIZE :: 0x0005 -WM_ACTIVATE :: 0x0006; WA_INACTIVE :: 0; WA_ACTIVE :: 1; WA_CLICKACTIVE :: 2 -WM_SETFOCUS :: 0x0007; WM_KILLFOCUS :: 0x0008; WM_ENABLE :: 0x000A; WM_SETREDRAW :: 0x000B; WM_SETTEXT :: 0x000C; WM_GETTEXT :: 0x000D; WM_GETTEXTLENGTH :: 0x000E; WM_PAINT :: 0x000F; WM_CLOSE :: 0x0010 CW_USEDEFAULT :: -2147483648//0x80000000 @@ -92,3 +89,116 @@ SWP_NOSENDCHANGING :: 0x0400 SWP_NOSIZE :: 0x0001 SWP_NOZORDER :: 0x0004 SWP_SHOWWINDOW :: 0x0040 + +WM_NULL :: 0x0000; WM_CREATE :: 0x0001; WM_DESTROY :: 0x0002; WM_MOVE :: 0x0003; WM_SIZE :: 0x0005 +WM_ACTIVATE :: 0x0006; WA_INACTIVE :: 0; WA_ACTIVE :: 1; WA_CLICKACTIVE :: 2 +WM_SETFOCUS :: 0x0007; WM_KILLFOCUS :: 0x0008; WM_ENABLE :: 0x000A; WM_SETREDRAW :: 0x000B; WM_SETTEXT :: 0x000C; WM_GETTEXT :: 0x000D; WM_GETTEXTLENGTH :: 0x000E; WM_PAINT :: 0x000F; WM_CLOSE :: 0x0010 +WM_KEYFIRST :: 0x0100 +WM_KEYDOWN :: 0x0100 +WM_KEYUP :: 0x0101 +WM_CHAR :: 0x0102 +WM_DEADCHAR :: 0x0103 +WM_SYSKEYDOWN :: 0x0104 +WM_SYSKEYUP :: 0x0105 +WM_SYSCHAR :: 0x0106 +WM_SYSDEADCHAR :: 0x0107 + + +VK_BACK :: 0x08 +VK_TAB :: 0x09 + +/* + * 0x0A - 0x0B : reserved + */ + +VK_CLEAR :: 0x0C +VK_RETURN :: 0x0D + +/* + * 0x0E - 0x0F : unassigned + */ + +VK_SHIFT :: 0x10 +VK_CONTROL :: 0x11 +VK_MENU :: 0x12 +VK_PAUSE :: 0x13 +VK_CAPITAL :: 0x14 + +VK_KANA :: 0x15 +VK_HANGEUL :: 0x15 /* old name - should be here for compatibility */ +VK_HANGUL :: 0x15 +VK_IME_ON :: 0x16 +VK_JUNJA :: 0x17 +VK_FINAL :: 0x18 +VK_HANJA :: 0x19 +VK_KANJI :: 0x19 +VK_IME_OFF :: 0x1A + +VK_ESCAPE :: 0x1B + +VK_CONVERT :: 0x1C +VK_NONCONVERT :: 0x1D +VK_ACCEPT :: 0x1E +VK_MODECHANGE :: 0x1F + +VK_SPACE :: 0x20 +VK_PRIOR :: 0x21 +VK_NEXT :: 0x22 +VK_END :: 0x23 +VK_HOME :: 0x24 +VK_LEFT :: 0x25 +VK_UP :: 0x26 +VK_RIGHT :: 0x27 +VK_DOWN :: 0x28 +VK_SELECT :: 0x29 +VK_PRINT :: 0x2A +VK_EXECUTE :: 0x2B +VK_SNAPSHOT :: 0x2C +VK_INSERT :: 0x2D +VK_DELETE :: 0x2E +VK_HELP :: 0x2F + +/* + * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39) + * 0x3A - 0x40 : unassigned + * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) + */ + +VK_LWIN :: 0x5B +VK_RWIN :: 0x5C +VK_APPS :: 0x5D + +/* + * 0x5E : reserved + */ + +VK_SLEEP :: 0x5F + +VK_NUMPAD0 :: 0x60 +VK_NUMPAD1 :: 0x61 +VK_NUMPAD2 :: 0x62 +VK_NUMPAD3 :: 0x63 +VK_NUMPAD4 :: 0x64 +VK_NUMPAD5 :: 0x65 +VK_NUMPAD6 :: 0x66 +VK_NUMPAD7 :: 0x67 +VK_NUMPAD8 :: 0x68 +VK_NUMPAD9 :: 0x69 +VK_MULTIPLY :: 0x6A +VK_ADD :: 0x6B +VK_SEPARATOR :: 0x6C +VK_SUBTRACT :: 0x6D +VK_DECIMAL :: 0x6E +VK_DIVIDE :: 0x6F +VK_F1 :: 0x70 +VK_F2 :: 0x71 +VK_F3 :: 0x72 +VK_F4 :: 0x73 +VK_F5 :: 0x74 +VK_F6 :: 0x75 +VK_F7 :: 0x76 +VK_F8 :: 0x77 +VK_F9 :: 0x78 +VK_F10 :: 0x79 +VK_F11 :: 0x7A +VK_F12 :: 0x7B \ No newline at end of file diff --git a/modules/win32_multimedia.core b/modules/win32_multimedia.core index 6054da1..045501f 100644 --- a/modules/win32_multimedia.core +++ b/modules/win32_multimedia.core @@ -57,6 +57,11 @@ DrawBitmapInCompatibleDC :: (b: *Bitmap) SelectObject(b.hdc, b.dib) BitBlt(b.compatible_dc, 0, 0, b.size.x->int, b.size.y->int, b.hdc, 0, 0, SRCCOPY) +GetWindowStyle :: (resizable: Bool): DWORD + style: DWORD = WS_SYSMENU | WS_OVERLAPPED | WS_CAPTION + if resizable ;; style |= WS_MAXIMIZEBOX | WS_THICKFRAME | WS_MINIMIZEBOX + return style + GetWindowSize :: (window: HWND): Vec2I result: Vec2I window_rect: RECT @@ -88,18 +93,18 @@ SetWindowPosition :: (window: HWND, style: DWORD, pos: Vec2I): void AdjustWindowRect(window, style, &rect) SetWindowPos(window, 0, rect.left, rect.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE) -StartMultimedia :: (x: S64 = 1280, y: S64 = 720, title: String = "Hello people!"): Mu - mu: Mu +StartMultimedia :: (x: S64 = 1280, y: S64 = 720, title: String = "Hello people!", target_ms: F64 = 0.0166666) + Mu.time.delta = target_ms if timeBeginPeriod(1) == TIMERR_NOERROR - mu.os.good_scheduling = true + Mu.os.good_scheduling = true dpi_aware := SetProcessDPIAware() Assert(dpi_aware != 0) - mu.time.start = Time() + Mu.time.start = Time() hInstance := GetModuleHandleA(0) - window_name := StringToString16(&mu.frame_arena, title) + window_name := StringToString16(&Mu.frame_arena, title) w := WNDCLASSW{ lpfnWndProc = WindowProc, hInstance = hInstance, @@ -108,54 +113,197 @@ StartMultimedia :: (x: S64 = 1280, y: S64 = 720, title: String = "Hello people!" } Assert(RegisterClassW(&w) != 0) - style: DWORD = 0 - mu.os.window = CreateWindowExW( + style: DWORD = GetWindowStyle(false) + Mu.os.window = CreateWindowExW( dwExStyle = 0, hWndParent = 0, hMenu = 0, lpParam = 0, X = CW_USEDEFAULT, Y = CW_USEDEFAULT, nWidth = x->int, nHeight = y->int, lpClassName = window_name.str, lpWindowName = window_name.str, - dwStyle = WS_OVERLAPPEDWINDOW, + dwStyle = style, hInstance = hInstance ) - Assert(mu.os.window != 0) - SetWindowSize(mu.os.window, style, {x,y}) - ShowWindow(mu.os.window, SW_SHOW) + Assert(Mu.os.window != 0) + SetWindowSize(Mu.os.window, style, {x,y}) + ShowWindow(Mu.os.window, SW_SHOW) - size := GetWindowSize(mu.os.window) + size := GetWindowSize(Mu.os.window) Assert(size.x == x && size.y == y) - - mu.os.window_dc = GetDC(mu.os.window) - mu.os.bitmap = W32.CreateBitmap(mu.os.window_dc, size) - mu.scrn = mu.os.bitmap.data - mu.x = mu.os.bitmap.size.x - mu.y = mu.os.bitmap.size.y + Mu.os.window_dc = GetDC(Mu.os.window) + Mu.os.bitmap = W32.CreateBitmap(Mu.os.window_dc, size) - return mu + Mu.scrn = Mu.os.bitmap.data + Mu.x = Mu.os.bitmap.size.x + Mu.y = Mu.os.bitmap.size.y -UpdateMultimedia :: (mu: *Mu): Bool - mu.frame_count += 1 - frame_time := Time() - mu.time.frame_start - mu.time.total += frame_time - if frame_time < mu.time.delta - if mu.os.good_scheduling - time_to_sleep := (mu.time.delta - frame_time) * 1000 +UpdateMultimedia :: (): Bool + Mu.frame_count += 1 + frame_time := Time() - Mu.time.frame_start + Mu.time.total += frame_time + if frame_time < Mu.time.delta + if Mu.os.good_scheduling + time_to_sleep := (Mu.time.delta - frame_time) * 1000 if time_to_sleep > 0 time_to_sleep_dword := time_to_sleep->DWORD // @check if time_to_sleep_dword truncates down Sleep(time_to_sleep_dword) new_frame_time := Time() - for new_frame_time < mu.time.delta - new_frame_time = Time() - mu.time.frame_start + for new_frame_time < Mu.time.delta + new_frame_time = Time() - Mu.time.frame_start - mu.time.frame_start = Time() - return !mu.quit + Mu.time.frame_start = Time() + return !Mu.quit -AppIsRunning := true WindowProc :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT if msg == WM_DESTROY PostQuitMessage(0) - AppIsRunning = false return 0 + elif msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN + key := MapVKToKey(msg) + Mu.key[key].is_down = true + elif msg == WM_KEYUP || msg == WM_SYSKEYUP + key := MapVKToKey(msg) + Mu.key[key].is_down = false + + else;; return DefWindowProcW(hwnd, msg, wparam, lparam) + + +/*# +mapping = [ + ["Up", "VK_UP"], + ["Down", "VK_DOWN"], + ["Left", "VK_LEFT"], + ["Right", "VK_RIGHT"], + ["Escape", "VK_ESCAPE"], + ["Control", "VK_CONTROL"], + ["Backspace", "VK_BACK"], + ["Alt", "VK_MENU"], + ["Shift", "VK_SHIFT"], + ["Tab", "VK_TAB"], + ["F1", "VK_F1"], + ["F2", "VK_F2"], + ["F3", "VK_F3"], + ["F4", "VK_F4"], + ["F5", "VK_F5"], + ["F6", "VK_F6"], + ["F7", "VK_F7"], + ["F8", "VK_F8"], + ["F9", "VK_F9"], + ["F10", "VK_F10"], + ["F11", "VK_F11"], + ["F12", "VK_F12"], + ["A", "'A'"], + ["B", "'B'"], + ["C", "'C'"], + ["D", "'D'"], + ["E", "'E'"], + ["F", "'F'"], + ["G", "'G'"], + ["H", "'H'"], + ["I", "'I'"], + ["J", "'J'"], + ["K", "'K'"], + ["L", "'L'"], + ["M", "'M'"], + ["N", "'N'"], + ["O", "'O'"], + ["P", "'P'"], + ["Q", "'Q'"], + ["R", "'R'"], + ["S", "'S'"], + ["T", "'T'"], + ["U", "'U'"], + ["V", "'V'"], + ["W", "'W'"], + ["X", "'X'"], + ["Y", "'Y'"], + ["Z", "'Z'"], + ["K0", "'0'"], + ["K1", "'1'"], + ["K2", "'2'"], + ["K3", "'3'"], + ["K4", "'4'"], + ["K5", "'5'"], + ["K6", "'6'"], + ["K7", "'7'"], + ["K8", "'8'"], + ["K9", "'9'"], +] + +r = "Key :: enum\n " +for i,val in enumerate(mapping): + r += val[0] + if (i+1) % 10 == 0: r += "\n " + elif i != len(mapping)-1: r += ";" +print(r) + +print("MapVKToKey :: (vk: U32): Key") +el = "" +for val,map in mapping: + print(f" {el}if vk == {map} ;; return Key.{val}") + el = "el" +print(" Assert(false, \"Unidentified Virtual Key\")") +*/ +MapVKToKey :: (vk: U32): Key + if vk == VK_UP ;; return Key.Up + elif vk == VK_DOWN ;; return Key.Down + elif vk == VK_LEFT ;; return Key.Left + elif vk == VK_RIGHT ;; return Key.Right + elif vk == VK_ESCAPE ;; return Key.Escape + elif vk == VK_CONTROL ;; return Key.Control + elif vk == VK_BACK ;; return Key.Backspace + elif vk == VK_MENU ;; return Key.Alt + elif vk == VK_SHIFT ;; return Key.Shift + elif vk == VK_TAB ;; return Key.Tab + elif vk == VK_F1 ;; return Key.F1 + elif vk == VK_F2 ;; return Key.F2 + elif vk == VK_F3 ;; return Key.F3 + elif vk == VK_F4 ;; return Key.F4 + elif vk == VK_F5 ;; return Key.F5 + elif vk == VK_F6 ;; return Key.F6 + elif vk == VK_F7 ;; return Key.F7 + elif vk == VK_F8 ;; return Key.F8 + elif vk == VK_F9 ;; return Key.F9 + elif vk == VK_F10 ;; return Key.F10 + elif vk == VK_F11 ;; return Key.F11 + elif vk == VK_F12 ;; return Key.F12 + elif vk == 'A' ;; return Key.A + elif vk == 'B' ;; return Key.B + elif vk == 'C' ;; return Key.C + elif vk == 'D' ;; return Key.D + elif vk == 'E' ;; return Key.E + elif vk == 'F' ;; return Key.F + elif vk == 'G' ;; return Key.G + elif vk == 'H' ;; return Key.H + elif vk == 'I' ;; return Key.I + elif vk == 'J' ;; return Key.J + elif vk == 'K' ;; return Key.K + elif vk == 'L' ;; return Key.L + elif vk == 'M' ;; return Key.M + elif vk == 'N' ;; return Key.N + elif vk == 'O' ;; return Key.O + elif vk == 'P' ;; return Key.P + elif vk == 'Q' ;; return Key.Q + elif vk == 'R' ;; return Key.R + elif vk == 'S' ;; return Key.S + elif vk == 'T' ;; return Key.T + elif vk == 'U' ;; return Key.U + elif vk == 'V' ;; return Key.V + elif vk == 'W' ;; return Key.W + elif vk == 'X' ;; return Key.X + elif vk == 'Y' ;; return Key.Y + elif vk == 'Z' ;; return Key.Z + elif vk == '0' ;; return Key.K0 + elif vk == '1' ;; return Key.K1 + elif vk == '2' ;; return Key.K2 + elif vk == '3' ;; return Key.K3 + elif vk == '4' ;; return Key.K4 + elif vk == '5' ;; return Key.K5 + elif vk == '6' ;; return Key.K6 + elif vk == '7' ;; return Key.K7 + elif vk == '8' ;; return Key.K8 + elif vk == '9' ;; return Key.K9 + Assert(false, "Unidentified Virtual Key") +/*END*/ \ No newline at end of file