int CALLBACK WinMain(HINSTANCE Instance, HINSTANCE PrevInstance, LPSTR CommandLine, int ShowCode) { // Tick frequency { int64 TicksPerSecond; QueryPerformanceFrequency((LARGE_INTEGER *)&TicksPerSecond); Timer::Init(1000.0 / TicksPerSecond); } QueryPerformanceCounter((LARGE_INTEGER *)&Mem.Debug.Time); Timer::StartTime(&Mem.Debug.Timers[Timer_Startup]); Mem.IsRunning = true; // Set current path to this executable's path { HMODULE Module = GetModuleHandleA(NULL); char PathString[MAX_PATH]; uint32 PathLength = GetModuleFileNameA(Module, PathString, MAX_PATH); if (PathLength != -1) { char *LastSlash = strrchr(PathString, '\\'); if (LastSlash) { *LastSlash = '\0'; } SetCurrentDirectoryA(PathString); } } HWND Window; // Create Window { WNDCLASSA WindowClass = {}; WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; WindowClass.lpfnWndProc = Win32MainWindowCallback; WindowClass.hInstance = Instance; const char* IcoPath = "papaya.ico"; WindowClass.hIcon = (HICON)LoadImage(0, IcoPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED); WindowClass.lpszClassName = "PapayaWindowClass"; if (!RegisterClassA(&WindowClass)) { // TODO: Log: Register window class failed return 0; } Window = CreateWindowExA( 0, // Extended window style WindowClass.lpszClassName, // Class name, "Papaya", // Name, WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE, // Window style CW_USEDEFAULT, // X, CW_USEDEFAULT, // Y, CW_USEDEFAULT, // Width, CW_USEDEFAULT, // Height, 0, // Window Parent, 0, // Menu, Instance, // Handle to the instance, 0); // lpParam if (!Window) { // TODO: Log: Create window failed return 0; } SystemParametersInfo(SPI_GETWORKAREA, 0, &WindowsWorkArea, 0); #ifdef PAPAYARELEASE SetWindowPos(Window, HWND_TOP, 0, 0, 600, 600, NULL); ShowWindow(Window, SW_MAXIMIZE); #else uint32 ScreenWidth = GetSystemMetrics(SM_CXSCREEN); uint32 ScreenHeight = GetSystemMetrics(SM_CYSCREEN); Mem.Window.Width = (uint32)((float)ScreenWidth * 0.5); Mem.Window.Height = (uint32)((float)ScreenHeight * 0.8); uint32 WindowX = (ScreenWidth - Mem.Window.Width) / 2; uint32 WindowY = (ScreenHeight - Mem.Window.Height) / 2; SetWindowPos(Window, HWND_TOP, WindowX, WindowY, Mem.Window.Width, Mem.Window.Height, NULL); #endif // PAPAYARELEASE // Get window size { RECT WindowRect = { 0 }; BOOL foo = GetClientRect(Window, &WindowRect); Mem.Window.Width = WindowRect.right - WindowRect.left; Mem.Window.Height = WindowRect.bottom - WindowRect.top; } } // Initialize OpenGL { DeviceContext = GetDC(Window); // Setup pixel format { PIXELFORMATDESCRIPTOR PixelFormatDesc = { 0 }; // TODO: Program seems to work perfectly fine without all other params except dwFlags. // Can we skip other params for the sake of brevity? PixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR); PixelFormatDesc.nVersion = 1; PixelFormatDesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; PixelFormatDesc.iPixelType = PFD_TYPE_RGBA; PixelFormatDesc.cColorBits = 32; PixelFormatDesc.cDepthBits = 32; PixelFormatDesc.dwLayerMask = PFD_MAIN_PLANE; // int32 PixelFormat = ChoosePixelFormat(DeviceContext, &PixelFormatDesc); if (!PixelFormat) { exit(1); } // TODO: Log: Choose pixel format failed if (!SetPixelFormat(DeviceContext, PixelFormat, &PixelFormatDesc)) { exit(1); } // TODO: Log: Set pixel format failed } // Create rendering context { // TODO: Create "proper" context? // https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation HGLRC RenderingContext = wglCreateContext(DeviceContext); wglMakeCurrent(DeviceContext, RenderingContext); if (!GL::InitAndValidate()) { exit(1); } glGetIntegerv(GL_MAJOR_VERSION, &Mem.System.OpenGLVersion[0]); glGetIntegerv(GL_MINOR_VERSION, &Mem.System.OpenGLVersion[1]); } // Disable vsync if (wglewIsSupported("WGL_EXT_swap_control")) { wglSwapIntervalEXT(0); } } // Initialize tablet EasyTab_Load(Window); Core::Initialize(&Mem); // Initialize ImGui { ImGuiIO& io = ImGui::GetIO(); io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; io.KeyMap[ImGuiKey_UpArrow] = VK_UP; io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; io.KeyMap[ImGuiKey_Home] = VK_HOME; io.KeyMap[ImGuiKey_End] = VK_END; io.KeyMap[ImGuiKey_Delete] = VK_DELETE; io.KeyMap[ImGuiKey_Backspace] = VK_BACK; io.KeyMap[ImGuiKey_Enter] = VK_RETURN; io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; io.KeyMap[ImGuiKey_A] = 'A'; io.KeyMap[ImGuiKey_C] = 'C'; io.KeyMap[ImGuiKey_V] = 'V'; io.KeyMap[ImGuiKey_X] = 'X'; io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Z] = 'Z'; io.RenderDrawListsFn = Core::RenderImGui; io.ImeWindowHandle = Window; } Mem.Window.MenuHorizontalOffset = 32; Mem.Window.TitleBarButtonsWidth = 109; Mem.Window.TitleBarHeight = 30; Timer::StopTime(&Mem.Debug.Timers[Timer_Startup]); // Handle command line arguments (if present) if (strlen(CommandLine)) { // Remove double quotes from string if present { char* PtrRead = CommandLine; char* PtrWrite = CommandLine; while (*PtrRead) { *PtrWrite = *PtrRead++; if (*PtrWrite != '\"') { PtrWrite++; } } *PtrWrite = '\0'; } Core::OpenDocument(CommandLine, &Mem); } #ifdef PAPAYA_DEFAULT_IMAGE Core::OpenDocument(PAPAYA_DEFAULT_IMAGE, &Mem); #endif // PAPAYA_DEFAULT_IMAGE while (Mem.IsRunning) { Timer::StartTime(&Mem.Debug.Timers[Timer_Frame]); // Windows message handling { MSG Message; while (PeekMessage(&Message, 0, 0, 0, PM_REMOVE)) { if (Message.message == WM_QUIT) { Mem.IsRunning = false; } TranslateMessage(&Message); DispatchMessageA(&Message); } } // Tablet input // TODO: Put this in papaya.cpp { Mem.Tablet.Pressure = EasyTab->Pressure; Mem.Tablet.PosX = EasyTab->PosX; Mem.Tablet.PosY = EasyTab->PosY; Mem.Tablet.Buttons = EasyTab->Buttons; } BOOL IsMaximized = IsMaximized(Window); if (IsIconic(Window)) { goto EndOfFrame; } // Start new ImGui frame { ImGuiIO& io = ImGui::GetIO(); // Setup display size (every frame to accommodate for window resizing) RECT rect; GetClientRect(Window, &rect); io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Read keyboard modifiers inputs io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; // Setup time step INT64 current_time; QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); io.DeltaTime = (float)(current_time - Mem.Debug.Time) * (float)Timer::GetFrequency() / 1000.0f; Mem.Debug.Time = current_time; // TODO: Move Imgui timers from Debug to their own struct // Hide OS mouse cursor if ImGui is drawing it //SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW)); // Start the frame ImGui::NewFrame(); } // Title Bar Icon { ImGui::SetNextWindowSize(ImVec2((float)Mem.Window.MenuHorizontalOffset,(float)Mem.Window.TitleBarHeight)); ImGui::SetNextWindowPos(ImVec2(1.0f, 1.0f)); ImGuiWindowFlags WindowFlags = 0; // TODO: Create a commonly-used set of Window flags, and use them across ImGui windows WindowFlags |= ImGuiWindowFlags_NoTitleBar; WindowFlags |= ImGuiWindowFlags_NoResize; WindowFlags |= ImGuiWindowFlags_NoMove; WindowFlags |= ImGuiWindowFlags_NoScrollbar; WindowFlags |= ImGuiWindowFlags_NoCollapse; WindowFlags |= ImGuiWindowFlags_NoScrollWithMouse; ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(2,2)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); ImGui::PushStyleColor(ImGuiCol_WindowBg, Mem.Colors[PapayaCol_Transparent]); bool bTrue = true; ImGui::Begin("Title Bar Icon", &bTrue, WindowFlags); #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f) ImGui::Image((void*)(intptr_t)Mem.Textures[PapayaTex_UI], ImVec2(28,28), CALCUV(0,200), CALCUV(28,228)); #undef CALCUV ImGui::End(); ImGui::PopStyleColor(1); ImGui::PopStyleVar(5); } // Title Bar Buttons { ImGui::SetNextWindowSize(ImVec2((float)Mem.Window.TitleBarButtonsWidth,24.0f)); ImGui::SetNextWindowPos(ImVec2((float)Mem.Window.Width - Mem.Window.TitleBarButtonsWidth, 0.0f)); ImGuiWindowFlags WindowFlags = 0; WindowFlags |= ImGuiWindowFlags_NoTitleBar; WindowFlags |= ImGuiWindowFlags_NoResize; WindowFlags |= ImGuiWindowFlags_NoMove; WindowFlags |= ImGuiWindowFlags_NoScrollbar; WindowFlags |= ImGuiWindowFlags_NoCollapse; WindowFlags |= ImGuiWindowFlags_NoScrollWithMouse; ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); ImGui::PushStyleColor(ImGuiCol_Button, Mem.Colors[PapayaCol_Transparent]); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Mem.Colors[PapayaCol_ButtonHover]); ImGui::PushStyleColor(ImGuiCol_ButtonActive, Mem.Colors[PapayaCol_ButtonActive]); ImGui::PushStyleColor(ImGuiCol_WindowBg, Mem.Colors[PapayaCol_Transparent]); bool bTrue = true; #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f) ImGui::Begin("Title Bar Buttons", &bTrue, WindowFlags); ImGui::PushID(0); if(ImGui::ImageButton((void*)(size_t)Mem.Textures[PapayaTex_UI], ImVec2(34,26), CALCUV(62,200),CALCUV(96,226), 1, ImVec4(0,0,0,0))) { ShowWindow(Window, SW_MINIMIZE); } ImVec2 StartUV = IsMaximized ? CALCUV(28,226) : CALCUV(62,226); ImVec2 EndUV = IsMaximized ? CALCUV(62,252) : CALCUV(96,252); ImGui::PopID(); ImGui::SameLine(); ImGui::PushID(1); if(ImGui::ImageButton((void*)(size_t)Mem.Textures[PapayaTex_UI], ImVec2(34,26), StartUV, EndUV, 1, ImVec4(0,0,0,0))) { if (IsMaximized) { ShowWindow(Window, SW_RESTORE); } else { ShowWindow(Window, SW_MAXIMIZE); } } ImGui::PopID(); ImGui::SameLine(); ImGui::PushID(2); if(ImGui::ImageButton((void*)(size_t)Mem.Textures[PapayaTex_UI], ImVec2(34,26), CALCUV(28,200),CALCUV(62,226), 1, ImVec4(0,0,0,0))) { SendMessage(Window, WM_CLOSE, 0, 0); } ImGui::PopID(); ImGui::End(); #undef CALCUV ImGui::PopStyleVar(5); ImGui::PopStyleColor(4); } // ImGui::ShowTestWindow(); Core::UpdateAndRender(&Mem); SwapBuffers(DeviceContext); EndOfFrame: Timer::StopTime(&Mem.Debug.Timers[Timer_Frame]); double FrameRate = (Mem.CurrentTool == PapayaTool_Brush && Mem.Mouse.IsDown[0]) ? 500.0 : 60.0; double FrameTime = 1000.0 / FrameRate; double SleepTime = FrameTime - Mem.Debug.Timers[Timer_Frame].ElapsedMs; Mem.Debug.Timers[Timer_Sleep].ElapsedMs = SleepTime; if (SleepTime > 0) { Sleep((int32)SleepTime); } } Core::Shutdown(&Mem); EasyTab_Unload(); return 0; }
int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmd_line, int show_code) { timer::init(); QueryPerformanceCounter((LARGE_INTEGER *)&mem.profile); timer::start(Timer_Startup); mem.is_running = true; // Set current path to this executable's path { HMODULE module = GetModuleHandleA(NULL); char path_string[MAX_PATH]; uint32 path_len = GetModuleFileNameA(module, path_string, MAX_PATH); if (path_len != -1) { char *last_slash = strrchr(path_string, '\\'); if (last_slash) { *last_slash = '\0'; } SetCurrentDirectoryA(path_string); } } HWND window; // Create window { WNDCLASSA window_class = {}; window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; window_class.lpfnWndProc = Win32MainWindowCallback; window_class.hInstance = instance; const char* ico_path = "papaya.ico"; window_class.hIcon = (HICON)LoadImage(0, ico_path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED); window_class.lpszClassName = "PapayaWindowClass"; if (!RegisterClassA(&window_class)) { // TODO: Log: Register window class failed return 0; } window = CreateWindowExA( 0, // Extended window style window_class.lpszClassName, // Class name, "Papaya", // Name, WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE, // window style CW_USEDEFAULT, // X, CW_USEDEFAULT, // Y, CW_USEDEFAULT, // width, CW_USEDEFAULT, // height, 0, // window Parent, 0, // Menu, instance, // Handle to the instance, 0); // lpParam if (!window) { // TODO: Log: Create window failed return 0; } SystemParametersInfo(SPI_GETWORKAREA, 0, &windows_work_area, 0); #ifdef PAPAYARELEASE SetWindowPos(window, HWND_TOP, 0, 0, 600, 600, NULL); ShowWindow(window, SW_MAXIMIZE); #else uint32 screen_width = GetSystemMetrics(SM_CXSCREEN); uint32 screen_height = GetSystemMetrics(SM_CYSCREEN); mem.window.width = (uint32)((float)screen_width * 0.5); mem.window.height = (uint32)((float)screen_height * 0.8); uint32 window_x = (screen_width - mem.window.width) / 2; uint32 window_y = (screen_height - mem.window.height) / 2; SetWindowPos(window, HWND_TOP, window_x, window_y, mem.window.width, mem.window.height, NULL); #endif // PAPAYARELEASE // Get window size { RECT window_rect = { 0 }; BOOL foo = GetClientRect(window, &window_rect); mem.window.width = window_rect.right - window_rect.left; mem.window.height = window_rect.bottom - window_rect.top; } } // Initialize OpenGL { device_context = GetDC(window); // Setup pixel format { PIXELFORMATDESCRIPTOR pixel_format_desc = { 0 }; // TODO: Program seems to work perfectly fine without all other params except dwFlags. // Can we skip other params for the sake of brevity? pixel_format_desc.nSize = sizeof(PIXELFORMATDESCRIPTOR); pixel_format_desc.nVersion = 1; pixel_format_desc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; pixel_format_desc.iPixelType = PFD_TYPE_RGBA; pixel_format_desc.cColorBits = 32; pixel_format_desc.cDepthBits = 32; pixel_format_desc.dwLayerMask = PFD_MAIN_PLANE; // int32 pixel_format = ChoosePixelFormat(device_context, &pixel_format_desc); if (!pixel_format) { exit(1); } // TODO: Log: Choose pixel format failed if (!SetPixelFormat(device_context, pixel_format, &pixel_format_desc)) { exit(1); } // TODO: Log: Set pixel format failed } // Create rendering context { // TODO: Create "proper" context? // https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation HGLRC rendering_context = wglCreateContext(device_context); wglMakeCurrent(device_context, rendering_context); if (!gl_lite_init()) { exit(1); } glGetIntegerv(GL_MAJOR_VERSION, &mem.system.gl_version[0]); glGetIntegerv(GL_MINOR_VERSION, &mem.system.gl_version[1]); } // Disable vsync //if (wglewIsSupported("WGL_EXT_swap_control")) { wglSwapIntervalEXT(0); } } // Initialize tablet EasyTab_Load(window); core::init(&mem); // Initialize ImGui { ImGuiIO& io = ImGui::GetIO(); io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; io.KeyMap[ImGuiKey_UpArrow] = VK_UP; io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; io.KeyMap[ImGuiKey_Home] = VK_HOME; io.KeyMap[ImGuiKey_End] = VK_END; io.KeyMap[ImGuiKey_Delete] = VK_DELETE; io.KeyMap[ImGuiKey_Backspace] = VK_BACK; io.KeyMap[ImGuiKey_Enter] = VK_RETURN; io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; io.KeyMap[ImGuiKey_A] = 'A'; io.KeyMap[ImGuiKey_C] = 'C'; io.KeyMap[ImGuiKey_V] = 'V'; io.KeyMap[ImGuiKey_X] = 'X'; io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Z] = 'Z'; io.RenderDrawListsFn = core::render_imgui; io.ImeWindowHandle = window; } mem.window.menu_horizontal_offset = 32; mem.window.title_bar_buttons_width = 109; mem.window.title_bar_height = 30; timer::stop(Timer_Startup); // Handle command line arguments (if present) if (strlen(cmd_line)) { // Remove double quotes from string if present char* ptr_read = cmd_line; char* ptr_write = cmd_line; while (*ptr_read) { *ptr_write = *ptr_read++; if (*ptr_write != '\"') { ptr_write++; } } *ptr_write = '\0'; core::open_doc(cmd_line, &mem); } #ifdef PAPAYA_DEFAULT_IMAGE core::open_doc(PAPAYA_DEFAULT_IMAGE, &mem); #endif // PAPAYA_DEFAULT_IMAGE while (mem.is_running) { timer::start(Timer_Frame); // Windows message handling { MSG msg; while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { mem.is_running = false; } TranslateMessage(&msg); DispatchMessageA(&msg); } } // Tablet input // TODO: Put this in papaya.cpp { mem.tablet.pressure = EasyTab->Pressure; mem.tablet.pos.x = EasyTab->PosX; mem.tablet.pos.y = EasyTab->PosY; mem.tablet.buttons = EasyTab->Buttons; } BOOL is_maximized = IsMaximized(window); if (IsIconic(window)) { goto EndOfFrame; } // Start new ImGui frame { ImGuiIO& io = ImGui::GetIO(); // Setup display size (every frame to accommodate for window resizing) RECT rect; GetClientRect(window, &rect); io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Read keyboard modifiers inputs io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; // Setup time step INT64 current_time; QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); io.DeltaTime = (float)(current_time - mem.profile.current_time) * (float)timer::get_freq() / 1000.0f; mem.profile.current_time = current_time; // TODO: Move Imgui timers from Debug to their own struct // Hide OS mouse cursor if ImGui is drawing it //SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW)); // Start the frame ImGui::NewFrame(); } // Title Bar Icon { ImGui::SetNextWindowSize(ImVec2((float)mem.window.menu_horizontal_offset,(float)mem.window.title_bar_height)); ImGui::SetNextWindowPos(ImVec2(1.0f, 1.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(2,2)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); ImGui::PushStyleColor(ImGuiCol_WindowBg, mem.colors[PapayaCol_Transparent]); bool bTrue = true; ImGui::Begin("Title Bar Icon", &bTrue, mem.window.default_imgui_flags); #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f) ImGui::Image((void*)(intptr_t)mem.textures[PapayaTex_UI], ImVec2(28,28), CALCUV(0,200), CALCUV(28,228)); #undef CALCUV ImGui::End(); ImGui::PopStyleColor(1); ImGui::PopStyleVar(5); } // Title Bar Buttons { ImGui::SetNextWindowSize(ImVec2((float)mem.window.title_bar_buttons_width,24.0f)); ImGui::SetNextWindowPos(ImVec2((float)mem.window.width - mem.window.title_bar_buttons_width, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); ImGui::PushStyleColor(ImGuiCol_Button, mem.colors[PapayaCol_Transparent]); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, mem.colors[PapayaCol_ButtonHover]); ImGui::PushStyleColor(ImGuiCol_ButtonActive, mem.colors[PapayaCol_ButtonActive]); ImGui::PushStyleColor(ImGuiCol_WindowBg, mem.colors[PapayaCol_Transparent]); bool bTrue = true; #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f) ImGui::Begin("Title Bar Buttons", &bTrue, mem.window.default_imgui_flags); ImGui::PushID(0); if(ImGui::ImageButton((void*)(size_t)mem.textures[PapayaTex_UI], ImVec2(34,26), CALCUV(62,200), CALCUV(96,226), 1, ImVec4(0,0,0,0))) { ShowWindow(window, SW_MINIMIZE); } ImVec2 start_uv = is_maximized ? CALCUV(28,226) : CALCUV(62,226); ImVec2 end_uv = is_maximized ? CALCUV(62,252) : CALCUV(96,252); ImGui::PopID(); ImGui::SameLine(); ImGui::PushID(1); if(ImGui::ImageButton((void*)(size_t)mem.textures[PapayaTex_UI], ImVec2(34,26), start_uv, end_uv, 1, ImVec4(0,0,0,0))) { if (is_maximized) { ShowWindow(window, SW_RESTORE); } else { ShowWindow(window, SW_MAXIMIZE); } } ImGui::PopID(); ImGui::SameLine(); ImGui::PushID(2); if(ImGui::ImageButton((void*)(size_t)mem.textures[PapayaTex_UI], ImVec2(34,26), CALCUV(28,200), CALCUV(62,226), 1, ImVec4(0,0,0,0))) { SendMessage(window, WM_CLOSE, 0, 0); } ImGui::PopID(); ImGui::End(); #undef CALCUV ImGui::PopStyleVar(5); ImGui::PopStyleColor(4); } // ImGui::ShowTestWindow(); core::update(&mem); SwapBuffers(device_context); EndOfFrame: timer::stop(Timer_Frame); double frame_rate = (mem.current_tool == PapayaTool_Brush && mem.mouse.is_down[0]) ? 500.0 : 60.0; double frame_time = 1000.0 / frame_rate; double sleep_time = frame_time - timers[Timer_Frame].elapsed_ms; timers[Timer_Sleep].elapsed_ms = sleep_time; if (sleep_time > 0) { Sleep((int32)sleep_time); } } core::destroy(&mem); EasyTab_Unload(); return 0; }