summaryrefslogtreecommitdiff
path: root/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'core.c')
-rw-r--r--core.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/core.c b/core.c
new file mode 100644
index 0000000..96ba866
--- /dev/null
+++ b/core.c
@@ -0,0 +1,150 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <assert.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;
+
+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 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 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 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:
+ if (e.motion.state & SDL_BUTTON_RMASK) {
+ pos_x -= (double) e.motion.xrel / scale;
+ pos_y -= (double) e.motion.yrel / scale;
+ refresh = true;
+ }
+ mouse_x = e.motion.x;
+ mouse_y = e.motion.y;
+ break;
+ case SDL_MOUSEWHEEL:
+ if (e.wheel.y == 0) break;
+ add_scale((double) e.wheel.y / 2);
+ refresh = true;
+ break;
+ default:
+ break;
+ }
+ }
+ 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;
+ }
+ int 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(argv[0]);
+ viewer = create_viewer(mem_fd, renderer);
+ if (!viewer) abort();
+ atexit(cleanup);
+
+ goto_addr(0x7fea87727000);
+
+ 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);
+ }
+}