Video version of the code
This commit is contained in:
148
c/bounce.c
Normal file
148
c/bounce.c
Normal file
@ -0,0 +1,148 @@
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define MAX_WINDOWS 1024
|
||||
|
||||
// == globals ==
|
||||
uint32_t res_y;
|
||||
void globals_update() {
|
||||
res_y = GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
|
||||
// == bodies ==
|
||||
typedef struct body_t {
|
||||
float offset_y;
|
||||
float velocity;
|
||||
} body_t;
|
||||
|
||||
void body_init(body_t* body) {
|
||||
body->offset_y = 0.5;
|
||||
body->velocity = 0.0;
|
||||
}
|
||||
|
||||
void body_update(body_t* body, int32_t *y_ptr) {
|
||||
int32_t y = *y_ptr;
|
||||
|
||||
float y_float = y + body->offset_y;
|
||||
|
||||
for (size_t step = 0; step < 100; step++) {
|
||||
body->velocity += 0.0002;
|
||||
y_float += body->velocity;
|
||||
|
||||
if (y_float > res_y && body->velocity > 0) {
|
||||
body->velocity = -body->velocity * 0.75;
|
||||
if (-body->velocity < 0.05) {
|
||||
body->velocity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*y_ptr = min((int) y_float, res_y);
|
||||
|
||||
body->offset_y = y_float - *y_ptr;
|
||||
}
|
||||
|
||||
// == 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 x = xy.x, y = xy.y;
|
||||
body_update(&mouse_body.body, &y);
|
||||
SetCursorPos(x, 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);
|
||||
|
||||
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, &y);
|
||||
|
||||
int32_t height = rect.bottom - rect.top;
|
||||
SetWindowPos(
|
||||
windows[i].window, 0,
|
||||
x, y - height,
|
||||
-1, -1,
|
||||
SWP_NOACTIVATE | SWP_NOSIZE |
|
||||
SWP_NOZORDER | SWP_ASYNCWINDOWPOS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// == main ==
|
||||
int main() {
|
||||
mouse_init();
|
||||
window_init();
|
||||
|
||||
while (1) {
|
||||
globals_update();
|
||||
|
||||
mouse_update();
|
||||
window_update();
|
||||
|
||||
Sleep(1000/120);
|
||||
}
|
||||
}
|
BIN
c/bounce.exe
Normal file
BIN
c/bounce.exe
Normal file
Binary file not shown.
BIN
c/bounce.pdb
Normal file
BIN
c/bounce.pdb
Normal file
Binary file not shown.
Reference in New Issue
Block a user