summaryrefslogtreecommitdiff
path: root/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'core.c')
-rw-r--r--core.c226
1 files changed, 0 insertions, 226 deletions
diff --git a/core.c b/core.c
deleted file mode 100644
index de685b6..0000000
--- a/core.c
+++ /dev/null
@@ -1,226 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <assert.h>
-#include <signal.h>
-#include <SDL.h>
-
-#include "procfs.h"
-#include "memview.h"
-
-static int screen_width = 640;
-static int screen_height = 480;
-
-static double scale = 5;
-static double pos_x = 1024;
-static double pos_y = 0;
-
-static int mouse_x = 0;
-static int mouse_y = 0;
-
-SDL_Window *window = NULL;
-SDL_Renderer *renderer = NULL;
-
-pid_t pid;
-int mem_fd;
-struct viewer *viewer;
-
-static void add_scale(double amount) {
- pos_x += mouse_x / scale;
- pos_y += mouse_y / scale;
- scale += amount;
- if (scale > 50) scale = 50;
- else if (scale < 0.5) scale = 0.5;
- pos_x -= mouse_x / scale;
- pos_y -= mouse_y / scale;
-}
-
-static void world_pos(double *x, double *y) {
- *x = *x / scale + floor(pos_x);
- *y = *y / scale + floor(pos_y);
-}
-
-static void goto_addr(uintptr_t addr) {
- int x, y;
- to_pos(addr, &x, &y);
- pos_x = x; pos_y = y;
- pos_x -= (double) screen_width / 2 * scale;
- pos_y -= (double) screen_height / 2 * scale;
-}
-
-static size_t current_map = 0;
-
-static void next_map() {
- struct procfs_map *maps;
- int n = procfs_maps(pid, &maps);
- if (n < 1) return;
- for (int i = 0; i < n; i++) {
- current_map = (current_map + 1) % n;
- if (maps[current_map].prot & PROT_READ)
- break;
- }
- goto_addr(maps[current_map].base);
- free(maps);
-}
-
-static void prev_map() {
- struct procfs_map *maps;
- int n = procfs_maps(pid, &maps);
- if (n < 1) return;
- for (int i = 0; i < n; i++) {
- current_map = current_map > 1 ? current_map - 1 : n - 1;
- if (maps[current_map].prot & PROT_READ)
- break;
- }
- goto_addr(maps[current_map].base);
- free(maps);
-}
-
-static void report_error() {
- fprintf(stderr, "SDL Error: %s\n", SDL_GetError());
- exit(-1);
-}
-
-static void init_sdl(const char *title) {
- if (SDL_Init(SDL_INIT_VIDEO) < 0) report_error();
- window = SDL_CreateWindow(title,
- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
- screen_width, screen_height,
- SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
- if (window == NULL) report_error();
- renderer = SDL_CreateRenderer(window, -1, 0);
- if (renderer == NULL) report_error();
-}
-
-static void deinit_sdl() {
- SDL_DestroyRenderer(renderer);
- SDL_DestroyWindow(window);
- 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;
- while (SDL_PollEvent(&e)) {
- switch (e.type) {
- case SDL_QUIT:
- exit(0); break;
- case SDL_WINDOWEVENT:
- switch (e.window.event) {
- case SDL_WINDOWEVENT_RESIZED:
- screen_width = e.window.data1;
- screen_height = e.window.data2;
- SDL_SetWindowSize(window, screen_width, screen_height);
- refresh = true;
- break;
- case SDL_WINDOWEVENT_EXPOSED:
- refresh = true;
- break;
- default:
- break;
- }
- break;
- 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);
- refresh = true;
- break;
- case SDL_KEYDOWN:
- switch (e.key.keysym.sym) {
- case SDLK_RIGHT:
- next_map();
- refresh = true;
- break;
- case SDLK_LEFT:
- prev_map();
- refresh = true;
- break;
- case SDLK_SPACE:;
- static bool stopped = false;
- kill(pid, stopped ? SIGSTOP : SIGCONT);
- stopped = !stopped;
- break;
- default:
- break;
- }
- default:
- break;
- }
- }
- if (render_pages(viewer, pos_x, pos_y,
- screen_width, screen_height, scale, refresh))
- SDL_RenderPresent(renderer);
-}
-
-void cleanup() {
- destroy_viewer(viewer);
- deinit_sdl();
-}
-
-int main(int argc, char *argv[]) {
- if (argc < 2) {
- fprintf(stderr, "todo: show usage\n");
- return -1;
- }
- pid = atoi(argv[1]);
- if (pid == 0) {
- fprintf(stderr, "todo: show usage\n");
- return -1;
- }
- mem_fd = procfs_open(pid);
- if (mem_fd == -1) perror("error attaching to process");
-
- char title[1024];
- snprintf(title, 1024, "%s [%d]", argv[0], pid);
- init_sdl(title);
- viewer = create_viewer(mem_fd, renderer);
- if (!viewer) abort();
- atexit(cleanup);
-
- prev_map();
-
- int last_time = 0;
- int current_time = 0;
- while (1) {
- handle_events();
- last_time = current_time;
- current_time = SDL_GetTicks();
- int elapsed = current_time - last_time;
- if (elapsed < 1000 / 30)
- SDL_Delay(1000 / 30 - elapsed);
- }
-}