fix: missing files; resize wm code
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.0 MiB |
+260
-168
@@ -1,275 +1,367 @@
|
||||
#include <windows.h>
|
||||
/*
|
||||
Anytime I edit any C++ Code, in specifically Win32 code i get acute seizures cause of the naming
|
||||
conventions. I hope that whoever came up with these fuckass names gets fucked by a femboy. idk.
|
||||
|
||||
Anyways this is under the AGPL3.0 License so do whatever you want under that license terms.
|
||||
|
||||
Quick description of the app:
|
||||
- A hyrax picture which bounces around your desktop, like bonzi buddy but not destructive, more of a fun thing which you can open
|
||||
when you get bored.
|
||||
- Run the exe youll find out.
|
||||
|
||||
This is not malware or a virus, its purely for fun and entertainment purpouses.
|
||||
|
||||
rattatwinko - 04/05/26
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <gdiplus.h>
|
||||
#include <cstring>
|
||||
#include <math.h>
|
||||
#include <objidl.h>
|
||||
#include <math.h>
|
||||
#include <cstring>
|
||||
|
||||
#pragma comment(lib, "gdiplus.lib")
|
||||
|
||||
using namespace Gdiplus;
|
||||
|
||||
Image* LoadImageFromResource(int resId) {
|
||||
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(resId), RT_RCDATA);
|
||||
if (!hRes) return NULL;
|
||||
// consts
|
||||
static constexpr double GRAVITY = 1200.0;
|
||||
static constexpr double RESTITUTION = 0.6;
|
||||
static constexpr double AIR_DRAG = 0.999;
|
||||
static constexpr double GROUND_FRICTION = 0.8;
|
||||
static constexpr double REST_THRESHOLD = 5.0;
|
||||
static constexpr UINT TIMER_MS = 10;
|
||||
static constexpr int IMAGE_RESOURCE = 111;
|
||||
static constexpr int RESIZE_BORDER = 12; // make wider so easier grab
|
||||
|
||||
DWORD size = SizeofResource(NULL, hRes);
|
||||
if (size == 0) return NULL;
|
||||
// globals
|
||||
static ULONG_PTR g_gdiplusToken = 0;
|
||||
static Image* g_image = nullptr;
|
||||
static int g_winW = 640;
|
||||
static int g_winH = 480;
|
||||
static LARGE_INTEGER g_freq = {};
|
||||
|
||||
HGLOBAL hData = LoadResource(NULL, hRes);
|
||||
if (!hData) return NULL;
|
||||
// physics states
|
||||
static double g_x = 200.0, g_y = 50.0;
|
||||
static double g_vx = 0.0, g_vy = 0.0;
|
||||
static double g_lastTime = 0.0;
|
||||
|
||||
// resize status
|
||||
static bool g_resizing = false;
|
||||
static bool g_dragging = false;
|
||||
static int g_dragOffsetX = 0;
|
||||
static int g_dragOffsetY = 0;
|
||||
static POINT g_lastMouse = {};
|
||||
static double g_lastMouseTime = 0.0;
|
||||
|
||||
// helper definitions
|
||||
static double Now() {
|
||||
LARGE_INTEGER t;
|
||||
QueryPerformanceCounter(&t);
|
||||
return static_cast<double>(t.QuadPart) / static_cast<double>(g_freq.QuadPart);
|
||||
}
|
||||
|
||||
static Image* LoadImageFromResource(HINSTANCE hInst, int resId) {
|
||||
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(resId), RT_RCDATA);
|
||||
if (!hRes) return nullptr;
|
||||
|
||||
DWORD size = SizeofResource(hInst, hRes);
|
||||
if (!size) return nullptr;
|
||||
|
||||
HGLOBAL hData = LoadResource(hInst, hRes);
|
||||
if (!hData) return nullptr;
|
||||
|
||||
void* pData = LockResource(hData);
|
||||
if (!pData) return NULL;
|
||||
if (!pData) return nullptr;
|
||||
|
||||
HGLOBAL hBuffer = GlobalAlloc(GMEM_MOVEABLE, size);
|
||||
if (!hBuffer) return NULL;
|
||||
HGLOBAL hBuf = GlobalAlloc(GMEM_MOVEABLE, size);
|
||||
if (!hBuf) return nullptr;
|
||||
|
||||
void* pBuffer = GlobalLock(hBuffer);
|
||||
if (!pBuffer) {
|
||||
GlobalFree(hBuffer);
|
||||
return NULL;
|
||||
}
|
||||
void* pBuf = GlobalLock(hBuf);
|
||||
if (!pBuf) { GlobalFree(hBuf); return nullptr; }
|
||||
|
||||
memcpy(pBuffer, pData, size);
|
||||
GlobalUnlock(hBuffer);
|
||||
memcpy(pBuf, pData, size);
|
||||
GlobalUnlock(hBuf);
|
||||
|
||||
IStream* stream = NULL;
|
||||
HRESULT hr = CreateStreamOnHGlobal(hBuffer, TRUE, &stream);
|
||||
if (FAILED(hr) || !stream) {
|
||||
GlobalFree(hBuffer);
|
||||
return NULL;
|
||||
IStream* stream = nullptr;
|
||||
if (FAILED(CreateStreamOnHGlobal(hBuf, TRUE, &stream)) || !stream) {
|
||||
GlobalFree(hBuf);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Image* img = Image::FromStream(stream);
|
||||
stream->Release();
|
||||
|
||||
if (!img || img->GetLastStatus() != Ok) {
|
||||
if (img) delete img;
|
||||
return NULL;
|
||||
delete img;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
// physics "engine"
|
||||
static void StepPhysics(double dt) {
|
||||
const int screenW = GetSystemMetrics(SM_CXSCREEN);
|
||||
const int screenH = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
double x = 200.0, y = 50.0;
|
||||
double vx = 0.0, vy = 0.0;
|
||||
g_vy += GRAVITY * dt;
|
||||
g_vx *= AIR_DRAG;
|
||||
g_vy *= AIR_DRAG;
|
||||
|
||||
double gravity = 1200.0;
|
||||
double restitution = 0.6;
|
||||
double air_drag = 0.999;
|
||||
double ground_friction = 0.8;
|
||||
g_x += g_vx * dt;
|
||||
g_y += g_vy * dt;
|
||||
|
||||
int win_w = 640;
|
||||
int win_h = 480;
|
||||
// left/ right monitor borders
|
||||
if (g_x < 0.0) {
|
||||
g_x = 0.0;
|
||||
g_vx = -g_vx * RESTITUTION;
|
||||
}
|
||||
else if (g_x > screenW - g_winW) {
|
||||
g_x = static_cast<double>(screenW - g_winW);
|
||||
g_vx = -g_vx * RESTITUTION;
|
||||
}
|
||||
|
||||
int dragging = 0;
|
||||
int offset_x = 0, offset_y = 0;
|
||||
// top
|
||||
if (g_y < 0.0) {
|
||||
g_y = 0.0;
|
||||
g_vy = -g_vy * RESTITUTION;
|
||||
}
|
||||
|
||||
POINT last_mouse;
|
||||
double last_mouse_time = 0.0;
|
||||
double last_time = 0.0;
|
||||
|
||||
LARGE_INTEGER freq;
|
||||
|
||||
ULONG_PTR gdiplusToken;
|
||||
Image* img = NULL;
|
||||
|
||||
|
||||
double now_time() {
|
||||
LARGE_INTEGER t;
|
||||
QueryPerformanceCounter(&t);
|
||||
return (double)t.QuadPart / (double)freq.QuadPart;
|
||||
// bottom
|
||||
if (g_y > screenH - g_winH) {
|
||||
g_y = static_cast<double>(screenH - g_winH);
|
||||
g_vy = -g_vy * RESTITUTION;
|
||||
g_vx *= GROUND_FRICTION;
|
||||
if (fabs(g_vy) < REST_THRESHOLD)
|
||||
g_vy = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
// win api window proc
|
||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (msg) {
|
||||
|
||||
// init the window
|
||||
case WM_CREATE: {
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceFrequency(&g_freq);
|
||||
|
||||
GdiplusStartupInput gdiplusStartupInput;
|
||||
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
|
||||
GdiplusStartupInput si;
|
||||
GdiplusStartup(&g_gdiplusToken, &si, nullptr);
|
||||
|
||||
img = LoadImageFromResource(111);
|
||||
HINSTANCE hInst = reinterpret_cast<CREATESTRUCT*>(lParam)->hInstance;
|
||||
g_image = LoadImageFromResource(hInst, IMAGE_RESOURCE);
|
||||
|
||||
if (!img || img->GetLastStatus() != Ok) {
|
||||
// MessageBoxA(NULL, "Image failed to load", "Error", MB_OK);
|
||||
}
|
||||
else {
|
||||
win_w = 640;
|
||||
win_h = 480;
|
||||
SetWindowPos(hwnd, NULL, 0, 0, win_w, win_h, SWP_NOMOVE);
|
||||
if (g_image) {
|
||||
g_winW = static_cast<int>(g_image->GetWidth());
|
||||
g_winH = static_cast<int>(g_image->GetHeight());
|
||||
SetWindowPos(hwnd, nullptr, 0, 0, g_winW, g_winH,
|
||||
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
SetTimer(hwnd, 1, 10, NULL);
|
||||
g_lastTime = Now();
|
||||
g_lastMouseTime = g_lastTime;
|
||||
|
||||
last_time = now_time();
|
||||
last_mouse_time = last_time;
|
||||
SetTimer(hwnd, 1, TIMER_MS, nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
// drag start
|
||||
case WM_LBUTTONDOWN: {
|
||||
dragging = 1;
|
||||
offset_x = LOWORD(lParam);
|
||||
offset_y = HIWORD(lParam);
|
||||
g_dragging = true;
|
||||
g_dragOffsetX = GET_X_LPARAM(lParam);
|
||||
g_dragOffsetY = GET_Y_LPARAM(lParam);
|
||||
g_vx = g_vy = 0.0;
|
||||
|
||||
vx = vy = 0;
|
||||
|
||||
GetCursorPos(&last_mouse);
|
||||
last_mouse_time = now_time();
|
||||
GetCursorPos(&g_lastMouse);
|
||||
g_lastMouseTime = Now();
|
||||
|
||||
SetCapture(hwnd);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETCURSOR:
|
||||
if (dragging)
|
||||
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
|
||||
else
|
||||
SetCursor(LoadCursor(NULL, IDC_HAND));
|
||||
return TRUE;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if (dragging) {
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
// drag move
|
||||
case WM_MOUSEMOVE: {
|
||||
if (!g_dragging) break;
|
||||
|
||||
double now = now_time();
|
||||
double dt = now - last_mouse_time;
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
|
||||
if (dt > 0) {
|
||||
vx = (p.x - last_mouse.x) / dt;
|
||||
vy = (p.y - last_mouse.y) / dt;
|
||||
}
|
||||
const double now = Now();
|
||||
const double dt = now - g_lastMouseTime;
|
||||
|
||||
last_mouse = p;
|
||||
last_mouse_time = now;
|
||||
|
||||
x = p.x - offset_x;
|
||||
y = p.y - offset_y;
|
||||
|
||||
SetWindowPos(hwnd, NULL, (int)x, (int)y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER);
|
||||
if (dt > 0.0) {
|
||||
g_vx = (p.x - g_lastMouse.x) / dt;
|
||||
g_vy = (p.y - g_lastMouse.y) / dt;
|
||||
}
|
||||
break;
|
||||
|
||||
g_lastMouse = p;
|
||||
g_lastMouseTime = now;
|
||||
|
||||
g_x = p.x - g_dragOffsetX;
|
||||
g_y = p.y - g_dragOffsetY;
|
||||
|
||||
SetWindowPos(hwnd, nullptr, static_cast<int>(g_x), static_cast<int>(g_y),
|
||||
0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
break;
|
||||
}
|
||||
|
||||
// drag end
|
||||
case WM_LBUTTONUP:
|
||||
dragging = 0;
|
||||
g_dragging = false;
|
||||
ReleaseCapture();
|
||||
break;
|
||||
|
||||
// while dragging nutz accross fohead disable OS from doing shit
|
||||
case WM_ENTERSIZEMOVE:
|
||||
g_resizing = true;
|
||||
break;
|
||||
|
||||
case WM_EXITSIZEMOVE: {
|
||||
g_resizing = false;
|
||||
g_vx = g_vy = 0.0;
|
||||
|
||||
// sync gx/y with resized cords
|
||||
RECT r;
|
||||
GetWindowRect(hwnd, &r);
|
||||
g_x = static_cast<double>(r.left);
|
||||
g_y = static_cast<double>(r.top);
|
||||
|
||||
g_lastTime = Now(); // after everything is clean then redraw
|
||||
break;
|
||||
}
|
||||
|
||||
// weird asf logic
|
||||
case WM_NCHITTEST: {
|
||||
POINT p = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
RECT r;
|
||||
GetWindowRect(hwnd, &r);
|
||||
|
||||
const bool left = p.x < r.left + RESIZE_BORDER;
|
||||
const bool right = p.x >= r.right - RESIZE_BORDER;
|
||||
const bool top = p.y < r.top + RESIZE_BORDER;
|
||||
const bool bottom = p.y >= r.bottom - RESIZE_BORDER;
|
||||
|
||||
if (top && left) return HTTOPLEFT;
|
||||
if (top && right) return HTTOPRIGHT;
|
||||
if (bottom && left) return HTBOTTOMLEFT;
|
||||
if (bottom && right) return HTBOTTOMRIGHT;
|
||||
if (left) return HTLEFT;
|
||||
if (right) return HTRIGHT;
|
||||
if (top) return HTTOP;
|
||||
if (bottom) return HTBOTTOM;
|
||||
return HTCLIENT;
|
||||
}
|
||||
|
||||
// sync dimensions after resizing
|
||||
case WM_SIZE:
|
||||
g_winW = LOWORD(lParam);
|
||||
g_winH = HIWORD(lParam);
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
break;
|
||||
|
||||
// cursor, bunch of this dont work
|
||||
case WM_SETCURSOR:
|
||||
if (LOWORD(lParam) == HTCLIENT) {
|
||||
SetCursor(LoadCursor(nullptr, g_dragging ? IDC_SIZEALL : IDC_HAND));
|
||||
return TRUE;
|
||||
}
|
||||
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
|
||||
// phyisks tick
|
||||
case WM_TIMER: {
|
||||
double now = now_time();
|
||||
double dt = now - last_time;
|
||||
last_time = now;
|
||||
const double now = Now();
|
||||
const double dt = now - g_lastTime;
|
||||
g_lastTime = now;
|
||||
|
||||
int screen_w = GetSystemMetrics(SM_CXSCREEN);
|
||||
int screen_h = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
if (!dragging) {
|
||||
vy += gravity * dt;
|
||||
|
||||
vx *= air_drag;
|
||||
vy *= air_drag;
|
||||
|
||||
x += vx * dt;
|
||||
y += vy * dt;
|
||||
|
||||
if (x <= 0) {
|
||||
x = 0;
|
||||
vx = -vx * restitution;
|
||||
}
|
||||
else if (x >= screen_w - win_w) {
|
||||
x = screen_w - win_w;
|
||||
vx = -vx * restitution;
|
||||
}
|
||||
|
||||
if (y >= screen_h - win_h) {
|
||||
y = screen_h - win_h;
|
||||
vy = -vy * restitution;
|
||||
vx *= ground_friction;
|
||||
|
||||
if (fabs(vy) < 5)
|
||||
vy = 0;
|
||||
}
|
||||
|
||||
if (y <= 0) {
|
||||
y = 0;
|
||||
vy = -vy * restitution;
|
||||
}
|
||||
|
||||
SetWindowPos(hwnd, NULL, (int)x, (int)y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER);
|
||||
if (!g_dragging && !g_resizing) {
|
||||
StepPhysics(dt);
|
||||
SetWindowPos(hwnd, nullptr, static_cast<int>(g_x), static_cast<int>(g_y),
|
||||
0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// pablo picasso
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
Graphics g(hdc);
|
||||
// db to avoid me floppin on the floor like a fish (cause of flashing lights)
|
||||
HDC memDC = CreateCompatibleDC(hdc);
|
||||
HBITMAP memBmp = CreateCompatibleBitmap(hdc, g_winW, g_winH);
|
||||
HGDIOBJ old = SelectObject(memDC, memBmp);
|
||||
|
||||
if (img)
|
||||
g.DrawImage(img, 0, 0, win_w, win_h);
|
||||
Graphics g(memDC);
|
||||
g.SetInterpolationMode(InterpolationModeHighQualityBicubic);
|
||||
|
||||
if (g_image)
|
||||
g.DrawImage(g_image, 0, 0, g_winW, g_winH);
|
||||
|
||||
BitBlt(hdc, 0, 0, g_winW, g_winH, memDC, 0, 0, SRCCOPY);
|
||||
|
||||
SelectObject(memDC, old);
|
||||
DeleteObject(memBmp);
|
||||
DeleteDC(memDC);
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
break;
|
||||
}
|
||||
|
||||
// escape destroy
|
||||
case WM_KEYDOWN:
|
||||
if (wParam == VK_ESCAPE)
|
||||
DestroyWindow(hwnd);
|
||||
else if (wParam == VK_SPACE)
|
||||
DestroyWindow(hwnd);
|
||||
break;
|
||||
|
||||
// consuela
|
||||
case WM_DESTROY:
|
||||
if (img) delete img;
|
||||
GdiplusShutdown(gdiplusToken);
|
||||
KillTimer(hwnd, 1);
|
||||
delete g_image;
|
||||
g_image = nullptr;
|
||||
GdiplusShutdown(g_gdiplusToken);
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int WINAPI wWinMain(
|
||||
HINSTANCE hInstance,
|
||||
HINSTANCE,
|
||||
PWSTR,
|
||||
int nCmdShow
|
||||
) {
|
||||
|
||||
if (IsDebuggerPresent())
|
||||
return 0;
|
||||
|
||||
WNDCLASSW wc = { 0 };
|
||||
// right around the entry point (reference to asshair guy)
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow) {
|
||||
WNDCLASSW wc = {};
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.lpszClassName = L"Hyrax";
|
||||
wc.hCursor = LoadCursor(NULL, IDC_HAND);
|
||||
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_HAND);
|
||||
RegisterClassW(&wc);
|
||||
|
||||
HWND hwnd = CreateWindowExW(
|
||||
WS_EX_TOPMOST,
|
||||
L"Hyrax",
|
||||
L"",
|
||||
L"Hyrax", L"",
|
||||
WS_POPUP,
|
||||
(int)x, (int)y,
|
||||
win_w, win_h,
|
||||
NULL, NULL, hInstance, NULL
|
||||
static_cast<int>(g_x), static_cast<int>(g_y),
|
||||
g_winW, g_winH,
|
||||
nullptr, nullptr, hInstance, nullptr
|
||||
);
|
||||
|
||||
if (!hwnd)
|
||||
return 1;
|
||||
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
MSG msg;
|
||||
while (GetMessageW(&msg, NULL, 0, 0)) {
|
||||
while (GetMessageW(&msg, nullptr, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return static_cast<int>(msg.wParam);
|
||||
}
|
||||
Reference in New Issue
Block a user