#define GF_EXPOSE_DRAW_PLATFORM #define GF_EXPOSE_DRAW #define GF_EXPOSE_INPUT #include /* External library */ #include /* Interface */ #include /* Engine */ #include #include #include #include /* Standard */ #include #include void gf_draw_platform_begin(void) {} void gf_draw_platform_end(void) {} LRESULT CALLBACK gf_draw_platform_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { PAINTSTRUCT ps; RECT rect; gf_draw_t* draw = (gf_draw_t*)GetWindowLongPtr(hWnd, GWLP_USERDATA); switch(msg) { case WM_PAINT: BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_SIZE: if(draw->platform != NULL) { GetClientRect(hWnd, &rect); draw->x = rect.left; draw->y = rect.top; draw->width = rect.right - rect.left; draw->height = rect.bottom - rect.top; gf_draw_reshape(draw); } break; case WM_MOUSEMOVE: if(draw->input != NULL) { draw->input->mouse_x = LOWORD(lp); draw->input->mouse_y = HIWORD(lp); } break; case WM_CLOSE: draw->close = 1; break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wp, lp); } return 0; } int gf_draw_platform_has_extension(gf_draw_t* draw, const char* query) { return 0; } int gf_draw_platform_step(gf_draw_t* draw) { MSG msg; int ret = 0; while(PeekMessage(&msg, draw->platform->window, 0, 0, PM_NOREMOVE)) { if(GetMessage(&msg, draw->platform->window, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { ret = 1; break; } } if(ret == 0) { gf_draw_driver_before(draw); gf_draw_frame(draw); gf_draw_driver_after(draw); SwapBuffers(draw->platform->dc); } return ret; } gf_draw_platform_t* gf_draw_platform_create(gf_engine_t* engine, gf_draw_t* draw) { WNDCLASSEX wc; RECT rect; DWORD style; gf_draw_platform_t* platform = malloc(sizeof(*platform)); memset(platform, 0, sizeof(*platform)); platform->engine = engine; platform->instance = (HINSTANCE)GetModuleHandle(NULL); if(platform->instance == NULL) { gf_log_function(engine, "Failed to get instance", ""); gf_draw_platform_destroy(platform); return NULL; } wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = gf_draw_platform_proc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = platform->instance; wc.hIcon = LoadIcon(platform->instance, "GAME"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "goldfish"; wc.hIconSm = LoadIcon(platform->instance, "GAME"); if(!RegisterClassEx(&wc)) { gf_log_function(engine, "Failed to register class", ""); gf_draw_platform_destroy(platform); return NULL; } platform->window = CreateWindow("goldfish", draw->title, (WS_OVERLAPPEDWINDOW), draw->x, draw->y, draw->width, draw->height, NULL, 0, platform->instance, NULL); if(platform->window == NULL) { gf_log_function(engine, "Failed to create window", ""); gf_draw_platform_destroy(platform); return NULL; } SetWindowLongPtr(platform->window, GWLP_USERDATA, (LONG_PTR)draw); platform->dc = GetDC(platform->window); SetRect(&rect, 0, 0, draw->width, draw->height); style = (DWORD)GetWindowLongPtr(platform->window, GWL_STYLE); AdjustWindowRect(&rect, style, FALSE); SetWindowPos(platform->window, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE); ShowWindow(platform->window, SW_NORMAL); UpdateWindow(platform->window); return platform; } void gf_draw_platform_destroy(gf_draw_platform_t* platform) { if(platform->dc != NULL) { ReleaseDC(platform->window, platform->dc); } if(platform->window != NULL) { DestroyWindow(platform->window); } gf_log_function(platform->engine, "Destroyed platform-dependent part of drawing driver", ""); free(platform); }