summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2023-02-07 18:07:48 -0600
committerthe lemons <citrons@mondecitronne.com>2023-02-07 18:07:48 -0600
commitc651762762dd9463aacecd703b31d81042a42473 (patch)
tree0418a376172a0d5c3688ec2b1f6308e1d5b9c3b8
parent4300520103c7196764561cdf7d34734495d708c0 (diff)
add drawing
-rw-r--r--core.c34
-rw-r--r--memview.c26
-rw-r--r--memview.h3
-rw-r--r--procfs.c24
-rw-r--r--procfs.h3
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