161 lines
3.5 KiB
C
161 lines
3.5 KiB
C
#include <math.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <time.h>
|
|
|
|
#define MAX_WINDOWS 1024
|
|
|
|
// resolution
|
|
uint32_t res_y;
|
|
void globals_init() {
|
|
res_y = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
|
|
// bodies
|
|
typedef struct body_t {
|
|
int32_t last_x;
|
|
int32_t last_y;
|
|
float offset_x;
|
|
float offset_y;
|
|
float velocity;
|
|
} body_t;
|
|
|
|
void body_init(body_t* body) {
|
|
body->last_x = -1;
|
|
body->last_y = -1;
|
|
body->offset_x = 0.5;
|
|
body->offset_y = 0.5;
|
|
body->velocity = 0.0;
|
|
}
|
|
|
|
void body_update(body_t* body, int32_t x, int32_t y, int32_t* x_new, int32_t* y_new) {
|
|
if (body->last_x != -1 && body->last_y != -1) {
|
|
int32_t dx = x - body->last_x;
|
|
int32_t dy = y - body->last_y;
|
|
double dist = sqrt((double) dx * dx + dy * dy);
|
|
body->velocity *= 1.0 - min(dist / 128, 1.0);
|
|
}
|
|
|
|
float float_x = x + body->offset_x;
|
|
float float_y = y + body->offset_y;
|
|
for (uint8_t step = 0; step < 100; step += 1) {
|
|
body->velocity += 0.0002;
|
|
|
|
float_y += body->velocity;
|
|
if (float_y > res_y && body->velocity > 0) {
|
|
body->velocity = -body->velocity * 0.75;
|
|
if (-body->velocity < 0.05) {
|
|
body->velocity = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
*x_new = (int) float_x;
|
|
*y_new = (int) float_y;
|
|
body->last_x = *x_new;
|
|
body->last_y = *y_new;
|
|
body->offset_x = float_x - *x_new;
|
|
body->offset_y = float_y - *y_new;
|
|
}
|
|
|
|
// == mouse ==
|
|
typedef struct mouse_body_t {
|
|
body_t body;
|
|
} mouse_body_t;
|
|
|
|
mouse_body_t mouse_body;
|
|
|
|
void mouse_init() {
|
|
body_init(&mouse_body.body);
|
|
}
|
|
|
|
void mouse_update() {
|
|
POINT xy;
|
|
GetCursorPos(&xy);
|
|
int32_t new_x, new_y;
|
|
body_update(&mouse_body.body, xy.x, xy.y, &new_x, &new_y);
|
|
SetCursorPos(new_x, new_y);
|
|
}
|
|
|
|
// == window ==
|
|
typedef struct window_body_t {
|
|
HWND window;
|
|
body_t body;
|
|
} window_body_t;
|
|
|
|
size_t n_windows;
|
|
window_body_t* windows;
|
|
size_t _n_new_windows;
|
|
window_body_t* _new_windows;
|
|
|
|
void window_init() {
|
|
n_windows = 0;
|
|
windows = calloc(sizeof(window_body_t), MAX_WINDOWS);
|
|
_n_new_windows = 0;
|
|
_new_windows = calloc(sizeof(window_body_t), MAX_WINDOWS);
|
|
}
|
|
|
|
BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) {
|
|
if (_n_new_windows >= MAX_WINDOWS) {
|
|
return 0;
|
|
}
|
|
if (!IsWindowVisible(window)) {
|
|
return 1;
|
|
}
|
|
window_body_t new;
|
|
new.window = window;
|
|
body_init(&new.body);
|
|
for (size_t i = 0; i < n_windows; i++) {
|
|
if (windows[i].window == new.window) {
|
|
new.body = windows[i].body;
|
|
break;
|
|
}
|
|
}
|
|
_new_windows[_n_new_windows++] = new;
|
|
return 1;
|
|
}
|
|
|
|
void window_enumerate() {
|
|
EnumWindows(window_handle_enum, 0);
|
|
|
|
// do the swap
|
|
window_body_t* tmp_windows = windows;
|
|
|
|
n_windows = _n_new_windows;
|
|
windows = _new_windows;
|
|
|
|
_n_new_windows = 0;
|
|
_new_windows = tmp_windows;
|
|
}
|
|
|
|
void window_update() {
|
|
window_enumerate();
|
|
|
|
for (size_t i = 0; i < n_windows; i++) {
|
|
RECT rect;
|
|
GetWindowRect(windows[i].window, &rect);
|
|
int32_t x = rect.left;
|
|
int32_t y = rect.bottom;
|
|
|
|
body_update(&windows[i].body, x, y, &x, &y);
|
|
|
|
int32_t height = rect.bottom - rect.top;
|
|
uint32_t flags = SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_ASYNCWINDOWPOS;
|
|
SetWindowPos(windows[i].window, 0, x, y - height, -1, -1, flags);
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
globals_init();
|
|
|
|
mouse_init();
|
|
window_init();
|
|
|
|
while (1) {
|
|
// mouse_update();
|
|
window_update();
|
|
|
|
Sleep(1000/120);
|
|
}
|
|
} |