From c651762762dd9463aacecd703b31d81042a42473 Mon Sep 17 00:00:00 2001 From: the lemons Date: Tue, 7 Feb 2023 18:07:48 -0600 Subject: add drawing --- core.c | 34 ++++++++++++++++++++++++++++------ memview.c | 26 +++++++++++++++++++++++++- memview.h | 3 ++- procfs.c | 24 +++++++++++++++++++----- procfs.h | 3 +++ 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/core.c b/core.c index b72f104..04cab5a 100644 --- a/core.c +++ b/core.c @@ -36,10 +36,9 @@ static void add_scale(double amount) { pos_y -= mouse_y / scale; } -static uintptr_t current_addr() { - return to_addr( - pos_x + screen_width / 2 * scale, - pos_y + screen_width / 2 * scale); +static void world_pos(double *x, double *y) { + *x = *x / scale + pos_x - 0.5; + *y = *y / scale + pos_y - 0.5; } static void goto_addr(uintptr_t addr) { @@ -100,6 +99,11 @@ static void deinit_sdl() { SDL_Quit(); } +static bool held(SDL_Keycode k) { + const uint8_t *state = SDL_GetKeyboardState(NULL); + return state[SDL_GetScancodeFromKey(k)]; +} + static void handle_events() { bool refresh = false; SDL_Event e; @@ -122,15 +126,33 @@ static void handle_events() { break; } break; - case SDL_MOUSEMOTION: - if (e.motion.state & SDL_BUTTON_RMASK) { + case SDL_MOUSEMOTION:; + uint32_t state = e.motion.state; + if (state & SDL_BUTTON_MMASK || + (state & SDL_BUTTON_RMASK && held(SDLK_LSHIFT))) { pos_x -= (double) e.motion.xrel / scale; pos_y -= (double) e.motion.yrel / scale; refresh = true; + } else if (state & (SDL_BUTTON_LMASK | SDL_BUTTON_RMASK)) { + double x1 = e.motion.x - e.motion.xrel; + double y1 = e.motion.y - e.motion.yrel; + double x2 = e.motion.x; double y2 = e.motion.y; + world_pos(&x1, &y1); world_pos(&x2, &y2); + pencil(viewer, + x1, y1, x2, y2, !(state & SDL_BUTTON_RMASK)); + refresh = true; } mouse_x = e.motion.x; mouse_y = e.motion.y; break; + case SDL_MOUSEBUTTONDOWN:; + double x = e.button.x; double y = e.button.y; + world_pos(&x, &y); + if (e.button.button == SDL_BUTTON_LEFT) + pencil(viewer, x, y, x, y, true); + else if (e.button.button == SDL_BUTTON_RIGHT) + pencil(viewer, x, y, x, y, false); + break; case SDL_MOUSEWHEEL: if (e.wheel.y == 0) break; add_scale((double) e.wheel.y / 2); diff --git a/memview.c b/memview.c index 7f7dbd4..95a3c6c 100644 --- a/memview.c +++ b/memview.c @@ -39,7 +39,8 @@ uintptr_t to_addr(int x, int y) { memcpy(&ux, &x, sizeof(unsigned int)); memcpy(&uy, &y, sizeof(unsigned int)); uintptr_t page = zorder(ux / PAGE_WIDTH, uy / PAGE_HEIGHT); - int offset = x % PAGE_WIDTH + y % PAGE_HEIGHT * PAGE_WIDTH; + int offset = + x % PAGE_WIDTH / CHAR_BIT + y % PAGE_HEIGHT * PAGE_WIDTH / CHAR_BIT; return page * PAGE_SIZE + offset; } @@ -135,3 +136,26 @@ bool render_pages(struct viewer *v, } return present; } + +static void write_bit(int fd, int x, int y, bool bit) { + uintptr_t addr = to_addr(x, y); + int bit_offs = x % CHAR_BIT; + uint8_t byte; + if (read_mem(fd, addr, &byte, 1) == -1) return; + byte = (byte & ~(1 << bit_offs)) | (bit << bit_offs); + write_mem(fd, addr, &byte, 1); +} + +void pencil(struct viewer *v, + double x1, double y1, double x2, double y2, bool bit) { + double dx = (x2 - x1); + double dy = (y2 - y1); + int step = abs(dx) >= abs(dy) ? abs(dx) : abs(dy); + dx = dx / step; dy = dy / step; + double x = x1; double y = y1; + for (int i = 0; i <= step; i++) { + write_bit(v->fd, x, y, bit); + x = x + dx; + y = y + dy; + } +} diff --git a/memview.h b/memview.h index 2a73ec4..47aab27 100644 --- a/memview.h +++ b/memview.h @@ -23,6 +23,7 @@ void destroy_viewer(struct viewer *v); bool render_pages(struct viewer *v, int x, int y, int width, int height, double scale, bool refresh); -void pencil(struct viewer *v, int x1, int y1, int x2, int y2, bool bit); +void pencil(struct viewer *v, + double x1, double y1, double x2, double y2, bool bit); #endif diff --git a/procfs.c b/procfs.c index 2558f03..1e70274 100644 --- a/procfs.c +++ b/procfs.c @@ -75,14 +75,28 @@ err: return -1; } -int read_page(int fd, uintptr_t index, uint8_t *data) { - if (lseek(fd, index * PAGE_SIZE, SEEK_SET) == -1) - return -1; +int read_mem(int fd, uintptr_t addr, uint8_t *data, size_t size) { + if (lseek(fd, addr, SEEK_SET) == -1) return -1; size_t n = 0; - while (n < PAGE_SIZE) { - ssize_t result = read(fd, data + n, PAGE_SIZE - n); + while (n < size) { + ssize_t result = read(fd, data + n, size - n); if (result == -1) return -1; n += result; } return 0; } + +int write_mem(int fd, uintptr_t addr, uint8_t *data, size_t size) { + if (lseek(fd, addr, SEEK_SET) == -1) return -1; + size_t n = 0; + while (n < size) { + ssize_t result = write(fd, data + n, size - n); + if (result == -1) return -1; + n += result; + } + return 0; +} + +int read_page(int fd, uintptr_t index, uint8_t *data) { + return read_mem(fd, index * PAGE_SIZE, data, PAGE_SIZE); +} diff --git a/procfs.h b/procfs.h index 28ef784..70a652e 100644 --- a/procfs.h +++ b/procfs.h @@ -11,6 +11,8 @@ #endif int procfs_open(pid_t pid); +int read_mem(int fd, uintptr_t addr, uint8_t *data, size_t size); +int write_mem(int fd, uintptr_t addr, uint8_t *data, size_t size); int read_page(int fd, uintptr_t index, uint8_t *data); struct procfs_map { @@ -20,5 +22,6 @@ struct procfs_map { }; ssize_t procfs_maps(pid_t pid, struct procfs_map **maps); +char procfs_state(pid_t pid); #endif -- cgit v1.2.3