diff options
| author | the lemons <citrons@mondecitronne.com> | 2023-02-05 19:06:16 -0600 |
|---|---|---|
| committer | the lemons <citrons@mondecitronne.com> | 2023-02-05 19:06:16 -0600 |
| commit | 3af50b956b8887b64c3c29b30a0008be866b24c4 (patch) | |
| tree | af2a6f736505585192f852342ae988a297024133 /core.c | |
initial commit
Diffstat (limited to 'core.c')
| -rw-r--r-- | core.c | 150 |
1 files changed, 150 insertions, 0 deletions
@@ -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); + } +} |
