Video version of the code

This commit is contained in:
Pyrex 2025-04-17 23:12:03 -07:00
parent 16b3b6fa1e
commit a28d2aca17
8 changed files with 83 additions and 270 deletions

2
bounce_c/.gitignore vendored
View File

@ -1,2 +0,0 @@
*.exe
*.pdb

View File

@ -1,72 +0,0 @@
from ctypes import POINTER, WINFUNCTYPE, byref, windll
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, POINT
import time
import math
user32 = windll.user32
gdi32 = windll.gdi32
user32.GetSystemMetrics.argtypes = [INT]
user32.GetCursorPos.argtypes = [LPPOINT]
user32.SetCursorPos.argtypes = [INT, INT]
CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM)
def get_mouse() -> tuple[int, int]:
point = POINT()
user32.GetCursorPos(byref(point))
x, y = point.x, point.y
return x, y
def get_resolution() -> tuple[int, int]:
SM_CXSCREEN = 0
SM_CYSCREEN = 1
return (
user32.GetSystemMetrics(SM_CXSCREEN),
user32.GetSystemMetrics(SM_CYSCREEN)
)
def set_mouse(x: int, y: int):
user32.SetCursorPos(x, y)
class MouseBody(object):
def __init__(self):
self._last_mouse = None
self.velocity = 0.0
def update(self):
mouse_x, mouse_y = get_mouse()
if self._last_mouse:
last_x, last_y = self._last_mouse
dx = mouse_x - last_x
dy = mouse_y - last_y
dist = math.sqrt(dx * dx + dy * dy)
# if they move the mouse they can fight it
# (but they have to move it a lot)
self.velocity *= 1.0 - min(dist / 64, 1.0)
_, res_y = get_resolution()
self.velocity += 1
new_y = int(mouse_y + self.velocity)
if new_y > res_y:
# simulate an inelastic collision
self.velocity = -self.velocity * 0.75
new_y = int(new_y + self.velocity)
set_mouse(mouse_x, new_y)
self._last_mouse = (mouse_x, new_y)
def main():
body = MouseBody()
while True:
time.sleep(1/120.0)
body.update()
if __name__ == "__main__":
main()

View File

@ -2,48 +2,36 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <windows.h> #include <windows.h>
#include <time.h>
#define MAX_WINDOWS 1024 #define MAX_WINDOWS 1024
// resolution // == globals ==
uint32_t res_y; uint32_t res_y;
void globals_init() { void globals_update() {
res_y = GetSystemMetrics(SM_CYSCREEN); res_y = GetSystemMetrics(SM_CYSCREEN);
} }
// bodies // == bodies ==
typedef struct body_t { typedef struct body_t {
int32_t last_x;
int32_t last_y;
float offset_x;
float offset_y; float offset_y;
float velocity; float velocity;
} body_t; } body_t;
void body_init(body_t* body) { 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->offset_y = 0.5;
body->velocity = 0.0; body->velocity = 0.0;
} }
void body_update(body_t* body, int32_t x, int32_t y, int32_t* x_new, int32_t* y_new) { void body_update(body_t* body, int32_t *y_ptr) {
if (body->last_x != -1 && body->last_y != -1) { int32_t y = *y_ptr;
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 y_float = y + body->offset_y;
float float_y = y + body->offset_y;
for (uint8_t step = 0; step < 100; step += 1) { for (size_t step = 0; step < 100; step++) {
body->velocity += 0.0002; body->velocity += 0.0002;
y_float += body->velocity;
float_y += body->velocity; if (y_float > res_y && body->velocity > 0) {
if (float_y > res_y && body->velocity > 0) {
body->velocity = -body->velocity * 0.75; body->velocity = -body->velocity * 0.75;
if (-body->velocity < 0.05) { if (-body->velocity < 0.05) {
body->velocity = 0; body->velocity = 0;
@ -51,12 +39,9 @@ void body_update(body_t* body, int32_t x, int32_t y, int32_t* x_new, int32_t* y_
} }
} }
*x_new = (int) float_x; *y_ptr = min((int) y_float, res_y);
*y_new = (int) float_y;
body->last_x = *x_new; body->offset_y = y_float - *y_ptr;
body->last_y = *y_new;
body->offset_x = float_x - *x_new;
body->offset_y = float_y - *y_new;
} }
// == mouse == // == mouse ==
@ -73,9 +58,9 @@ void mouse_init() {
void mouse_update() { void mouse_update() {
POINT xy; POINT xy;
GetCursorPos(&xy); GetCursorPos(&xy);
int32_t new_x, new_y; int32_t x = xy.x, y = xy.y;
body_update(&mouse_body.body, xy.x, xy.y, &new_x, &new_y); body_update(&mouse_body.body, &y);
SetCursorPos(new_x, new_y); SetCursorPos(x, y);
} }
// == window == // == window ==
@ -97,12 +82,9 @@ void window_init() {
} }
BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) { BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) {
if (_n_new_windows >= MAX_WINDOWS) { if (_n_new_windows >= MAX_WINDOWS) { return 0; }
return 0; if (!IsWindowVisible(window)) { return 1; }
}
if (!IsWindowVisible(window)) {
return 1;
}
window_body_t new; window_body_t new;
new.window = window; new.window = window;
body_init(&new.body); body_init(&new.body);
@ -119,7 +101,6 @@ BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) {
void window_enumerate() { void window_enumerate() {
EnumWindows(window_handle_enum, 0); EnumWindows(window_handle_enum, 0);
// do the swap
window_body_t* tmp_windows = windows; window_body_t* tmp_windows = windows;
n_windows = _n_new_windows; n_windows = _n_new_windows;
@ -138,22 +119,28 @@ void window_update() {
int32_t x = rect.left; int32_t x = rect.left;
int32_t y = rect.bottom; int32_t y = rect.bottom;
body_update(&windows[i].body, x, y, &x, &y); body_update(&windows[i].body, &y);
int32_t height = rect.bottom - rect.top; int32_t height = rect.bottom - rect.top;
uint32_t flags = SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_ASYNCWINDOWPOS; SetWindowPos(
SetWindowPos(windows[i].window, 0, x, y - height, -1, -1, flags); windows[i].window, 0,
x, y - height,
-1, -1,
SWP_NOACTIVATE | SWP_NOSIZE |
SWP_NOZORDER | SWP_ASYNCWINDOWPOS
);
} }
} }
// == main ==
int main() { int main() {
globals_init();
mouse_init(); mouse_init();
window_init(); window_init();
while (1) { while (1) {
// mouse_update(); globals_update();
mouse_update();
window_update(); window_update();
Sleep(1000/120); Sleep(1000/120);

BIN
c/bounce.exe Normal file

Binary file not shown.

BIN
c/bounce.pdb Normal file

Binary file not shown.

View File

@ -1,88 +0,0 @@
from ctypes import POINTER, WINFUNCTYPE, WinError, create_unicode_buffer, get_last_error, windll
from ctypes.wintypes import BOOL, DWORD, HBRUSH, HDC, HINSTANCE, HMENU, HWND, LPARAM, LPCWSTR, LPVOID, LPWSTR, INT, RECT
import time
user32 = windll.user32
gdi32 = windll.gdi32
CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM)
# thanks: https://stackoverflow.com/questions/37501191/how-to-get-windows-window-names-with-ctypes-in-python
def check_zero(result, func, args):
if not result:
err = get_last_error()
if err:
raise WinError(err)
return args
user32.CreateWindowExW.argtypes = [
DWORD, LPCWSTR, LPCWSTR, DWORD,
INT, INT, INT, INT,
HWND, HMENU, HINSTANCE, LPVOID
]
user32.CreateWindowExW.errcheck = check_zero
user32.FillRect.argtypes = [HDC, POINTER(RECT), HBRUSH]
user32.GetWindowDC.argtypes = [HWND]
user32.GetWindowDC.errcheck = check_zero
user32.GetWindowTextLengthW.argtypes = [HWND]
user32.GetWindowTextLengthW.errcheck = check_zero
user32.GetWindowTextW.argtypes = [HWND, LPWSTR, INT]
user32.GetWindowTextW.errcheck = check_zero
def find_all_windows():
windows = []
@CB_ENUM_WINDOWS
def _handle_window(hwnd, lparam):
# +1: make room for the null
length = user32.GetWindowTextLengthW(hwnd) + 1
buffer = create_unicode_buffer(length)
user32.GetWindowTextW(hwnd, buffer, length)
windows.append((hwnd, buffer.value))
return True
user32.EnumWindows(_handle_window, 0)
return windows
def fix_window(window):
"""
hdc = user32.GetWindowDC(window)
rect = RECT(0, 0, 10000, 10000)
brush = gdi32.CreateSolidBrush(0x00FF0000)
user32.FillRect(hdc, rect, brush)
gdi32.DeleteObject(brush)
print(window)
"""
classname = create_unicode_buffer("overlapper\x00")
windowname = create_unicode_buffer("overlapper\x00")
window = user32.CreateWindowExW(
0x08000000 | # WS_EX_NOACTIVATE
0x8 | # WS_EX_TOPMOST
0x0, # 0x20, # WS_EX_TRANSPARENT
classname,
windowname,
0x10000000, # WS_VISIBLE
0, 0, 128, 128, # x y w h
None, None,
None, None
)
user32.ShowWindow(window, 5) # SW_SHOW
def fix_step():
windows = find_all_windows()
for window_id, window_name in windows:
if window_name.endswith("Visual Studio Code"):
fix_window(window_id)
def main():
fix_step()
while True:
time.sleep(1)
if __name__ == "__main__":
main()

View File

@ -2,16 +2,14 @@ from abc import ABC, abstractmethod
from ctypes import WINFUNCTYPE, byref, windll from ctypes import WINFUNCTYPE, byref, windll
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, LPRECT, POINT, RECT from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, LPRECT, POINT, RECT
import time import time
import math
user32 = windll.user32 user32 = windll.user32
gdi32 = windll.gdi32
user32.GetSystemMetrics.argtypes = [INT]
user32.GetCursorPos.argtypes = [LPPOINT] user32.GetCursorPos.argtypes = [LPPOINT]
user32.SetCursorPos.argtypes = [INT, INT] user32.SetCursorPos.argtypes = [INT, INT]
user32.GetSystemMetrics.argtypes = [INT]
CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM)
user32.EnumWindows.argtypes = [CB_ENUM_WINDOWS, LPARAM] user32.EnumWindows.argtypes = [CB_ENUM_WINDOWS, LPARAM]
@ -20,13 +18,18 @@ user32.GetWindowRect.argtypes = [HWND, LPRECT]
user32.SetWindowPos.argtypes = [HWND, INT, INT, INT, INT, INT, INT] user32.SetWindowPos.argtypes = [HWND, INT, INT, INT, INT, INT, INT]
user32.IsWindowVisible.argtypes = [HWND] user32.IsWindowVisible.argtypes = [HWND]
def get_resolution_y() -> int:
SM_CYSCREEN = 1
return user32.GetSystemMetrics(SM_CYSCREEN)
class BouncyObject(ABC): class BouncyObject(ABC):
@abstractmethod @abstractmethod
def get_position(self) -> tuple[int, int]: def get_position(self) -> tuple[int, int]:
raise NotImplementedError raise NotImplementedError
@abstractmethod @abstractmethod
def set_position(self, xy: tuple[int, int]): def set_position(self, xy: tuple[int, int]) -> None:
raise NotImplementedError raise NotImplementedError
@ -50,10 +53,9 @@ class Window(BouncyObject):
user32.GetWindowRect(self._handle, byref(rect)) user32.GetWindowRect(self._handle, byref(rect))
return (rect.left, rect.bottom) return (rect.left, rect.bottom)
def set_position(self, xy: tuple[int, int]): def set_position(self, xy: tuple[int, int]) -> None:
rect = RECT() rect = RECT()
user32.GetWindowRect(self._handle, byref(rect)) user32.GetWindowRect(self._handle, byref(rect))
width = rect.right - rect.left
height = rect.bottom - rect.top height = rect.bottom - rect.top
x, y = xy x, y = xy
user32.SetWindowPos( user32.SetWindowPos(
@ -65,11 +67,37 @@ class Window(BouncyObject):
) )
class Body(object):
def __init__(self, controlled_object: BouncyObject):
self._last_offset: tuple[float, float] = (0.5, 0.5)
self._velocity = 0.0
self._controlled_object = controlled_object
def update(self, res_y: int) -> None:
x, y = self._controlled_object.get_position()
ox, oy = self._last_offset
x += ox
y += oy
for _ in range(100):
self._velocity += 0.0002
y += self._velocity
if y > res_y and self._velocity > 0:
self._velocity = -self._velocity * 0.75
if abs(self._velocity) < 0.05:
self._velocity = 0
x_int, y_int = int(x), min(int(y), res_y)
self._controlled_object.set_position((x_int, y_int))
self._last_offset = x - x_int, y - y_int
def enumerate_windows() -> list[int]: def enumerate_windows() -> list[int]:
windows: list[int] = [] windows: list[int] = []
@CB_ENUM_WINDOWS @CB_ENUM_WINDOWS
def _handle_window(hwnd, lparam): def _handle_window(hwnd: int, _lparam: int):
if user32.IsWindowVisible(hwnd): if user32.IsWindowVisible(hwnd):
windows.append(hwnd) windows.append(hwnd)
return True return True
@ -78,61 +106,19 @@ def enumerate_windows() -> list[int]:
return windows return windows
def get_resolution_y() -> int:
SM_CYSCREEN = 1
return user32.GetSystemMetrics(SM_CYSCREEN)
class Body(object):
def __init__(self, controlled_object: BouncyObject):
self._last_xy: tuple[int, int] | None =None
self._last_offset: tuple[float, float] = (0.5, 0.5)
self._velocity = 0.0
self._controlled_object = controlled_object
def update(self, res_y):
x, y = self._controlled_object.get_position()
ox, oy = self._last_offset
x += ox
y += oy
if self._last_xy:
last_x, last_y = self._last_xy
dx = x - last_x
dy = y - last_y
dist = math.sqrt(dx * dx + dy * dy)
# if they move the mouse they can fight it
# (but they have to move it a lot)
self._velocity *= 1.0 - min(dist / 128, 1.0)
for _ in range(100):
self._velocity += 0.0002
y += self._velocity
if y > res_y and self._velocity > 0:
self._velocity = -self._velocity * 0.75
if abs(self._velocity) < 0.05:
self._velocity = 0
self._controlled_object.set_position((int(x), int(y)))
self._last_xy = (int(x), int(y))
self._last_offset = (x % 1, y % 1)
class Bodies(object): class Bodies(object):
def __init__(self): def __init__(self):
self._mouse = Body(Mouse()) self._mouse = Body(Mouse())
self._windows = {} self._windows = {}
def update_list(self): def enumerate(self):
windows2 = {} windows_2 = {}
for i in enumerate_windows(): for i in enumerate_windows():
if existing := self._windows.get(i): if existing := self._windows.get(i):
windows2[i] = existing windows_2[i] = existing
else: else:
windows2[i] = Body(Window(i)) windows_2[i] = Body(Window(i))
self._windows = windows2 self._windows = windows_2
def get(self) -> list[Body]: def get(self) -> list[Body]:
return [self._mouse, *self._windows.values()] return [self._mouse, *self._windows.values()]
@ -143,11 +129,13 @@ def main():
while True: while True:
res_y = get_resolution_y() res_y = get_resolution_y()
bodies.update_list() bodies.enumerate()
print(len(bodies.get()));
for b in bodies.get(): for b in bodies.get():
b.update(res_y) b.update(res_y)
time.sleep(1/120.0)
time.sleep(1.0/120.0)
if __name__ == "__main__": if __name__ == "__main__":
main() main()