tis256-gui.c (5974B)
1#include "asm.h" 2#include "util.h" 3 4#include "raylib.h" 5#include "raymath.h" 6#include "tpu.h" 7 8#include <math.h> 9#include <string.h> 10 11#define TPU_PAD 15 12#define TPU_SIZE 160 13#define TPU_DIST (TPU_SIZE + 2 * TPU_PAD) 14 15struct tpu_info { 16 int inst_off; 17}; 18 19static uint16_t window_width = 0; 20static uint16_t window_height = 0; 21 22static bool drag = false; 23static Vector2 drag_mouse = { 0 }; 24static Vector2 drag_target = { 0 }; 25 26static float mouse_scroll = 0; 27static Vector2 mouse = { 0 }; 28 29static Camera2D camera = { 0 }; 30 31static struct tis tis = { 0 }; 32 33int (*cleanup)(void) = NULL; 34const char *progname = "tis256-gui"; 35 36static void 37draw_rect(float x, float y, float w, float h, Color c) 38{ 39 DrawRectangle((int) x, (int) y, (int) w, (int) h, c); 40} 41 42static void 43draw_text(float x, float y, const char *str, int size, Color c) 44{ 45 DrawText(str, (int) x, (int) y, size, c); 46} 47 48static void 49draw_tpu(struct tpu *tpu) 50{ 51 const int max_h = (TPU_SIZE - 8) / 8; 52 const int max_w = (TPU_SIZE - 8) / 5; 53 struct tpu_info *info; 54 char linebuf[32]; 55 int inst, off; 56 float sx, sy; 57 size_t len; 58 Vector2 v; 59 60 sx = (float) tpu->x * TPU_DIST; 61 sy = (float) tpu->y * TPU_DIST; 62 63 v = Vector2Transform((Vector2) { sx, sy }, GetCameraMatrix2D(camera)); 64 if (v.x >= window_width || v.y >= window_height) return; 65 66 v = Vector2Transform((Vector2) { sx + TPU_SIZE, sy + TPU_SIZE }, 67 GetCameraMatrix2D(camera)); 68 if (v.x < 0 || v.y < 0) return; 69 70 draw_rect(sx, sy, TPU_SIZE, TPU_SIZE, 71 tpu->status == STATUS_RUN ? GREEN : WHITE); 72 if (camera.zoom >= 1) { 73 draw_rect(sx + 2, sy + 2, TPU_SIZE - 4, TPU_SIZE - 4, BLACK); 74 info = tpu->user; 75 inst = info->inst_off; 76 for (off = 0; inst < TPU_MAX_INST; inst++) { 77 if (tpu->labels[inst]) { 78 len = strlen(tpu->labels[inst]); 79 snprintf(linebuf, 32, "%.*s:", max_w - 1, 80 tpu->labels[inst]); 81 draw_text(sx + 4, sy + 4 + (float) off * 8, 82 linebuf, 6, WHITE); 83 if (++off >= max_h) break; 84 } 85 if (inst < tpu->inst_cnt) { 86 asm_print_inst(linebuf, 32, &tpu->insts[inst]); 87 draw_text(sx + 4, sy + 4 + (float) off * 8, 88 linebuf, 6, WHITE); 89 if (++off >= max_h) break; 90 } 91 } 92 } 93 if (tpu->ports[DIR_LEFT].type != 0) 94 draw_rect(sx - TPU_PAD, sy + TPU_SIZE / 2.f, TPU_PAD, 4, 95 tpu->ports[DIR_LEFT].attached ? WHITE : RED); 96 if (tpu->ports[DIR_RIGHT].type != 0) 97 draw_rect(sx + TPU_SIZE, sy + TPU_SIZE / 2.f, TPU_PAD, 4, 98 tpu->ports[DIR_RIGHT].attached ? WHITE : RED); 99 if (tpu->ports[DIR_UP].type != 0) 100 draw_rect(sx + TPU_SIZE / 2.f, sy - TPU_PAD, 4, TPU_PAD, 101 tpu->ports[DIR_UP].attached ? WHITE : RED); 102 if (tpu->ports[DIR_DOWN].type != 0) 103 draw_rect(sx + TPU_SIZE / 2.f, sy + TPU_SIZE, 4, TPU_PAD, 104 tpu->ports[DIR_DOWN].attached ? WHITE : RED); 105} 106 107static struct tpu * 108in_tpu(Vector2 pos) 109{ 110 struct tpu *tpu; 111 float x, y; 112 size_t i; 113 114 for (tpu = tis.tpu_vec.tpus, i = 0; i < tis.tpu_vec.cnt; i++, tpu++) { 115 x = (float) tpu->x * TPU_DIST; 116 y = (float) tpu->y * TPU_DIST; 117 if (pos.x >= x && pos.x < x + TPU_SIZE 118 && pos.y >= y && pos.y < y + TPU_SIZE) 119 return tpu; 120 } 121 122 return NULL; 123} 124 125int 126main(int argc, const char **argv) 127{ 128 Vector2 wpos_prev, wpos; 129 struct tpu *tpu; 130 struct tpu_info *info; 131 float min_x, min_y; 132 float max_x, max_y; 133 double last_step; 134 FILE *tis_stdin, *tis_stdout; 135 float x, y; 136 size_t i; 137 138 if (argc < 2 || argc > 4) { 139 fprintf(stderr, "Usage: tis256-gui FILE [STDIN] [STDOUT]\n"); 140 exit(1); 141 } 142 143 tis_stdin = NULL; 144 if (argc >= 3) { 145 tis_stdin = fopen(argv[2], "r"); 146 if (!tis_stdin) die("fopen '%s':", argv[2]); 147 } 148 149 tis_stdout = NULL; 150 if (argc >= 4) { 151 tis_stdout = fopen(argv[3], "r"); 152 if (!tis_stdout) die("fopen '%s':", argv[3]); 153 } 154 155 tis_load(&tis, argv[1], tis_stdin, tis_stdout); 156 157 min_x = min_y = INFINITY; 158 max_x = max_y = -INFINITY; 159 for (tpu = tis.tpu_vec.tpus, i = 0; i < tis.tpu_vec.cnt; i++, tpu++) { 160 tpu->user = calloc(1, sizeof(struct tpu_info)); 161 if (!tpu->user) die("calloc:"); 162 x = (float) tpu->x * TPU_DIST; 163 y = (float) tpu->y * TPU_DIST; 164 min_x = MIN(min_x, x); 165 min_y = MIN(min_y, y); 166 max_x = MAX(max_x, x + TPU_SIZE); 167 max_y = MAX(max_y, y + TPU_SIZE); 168 } 169 if (min_x == INFINITY) min_x = min_y = max_x = max_y = 0; 170 171 SetConfigFlags(FLAG_WINDOW_RESIZABLE); 172 InitWindow(800, 600, "tis256-gui"); 173 SetTargetFPS(60); 174 175 camera.target.x = (min_x + max_x) / 2; 176 camera.target.y = (min_y + max_y) / 2; 177 camera.zoom = 1.f; 178 179 while (!WindowShouldClose()) { 180 if (IsWindowResized() || !window_width || !window_height) { 181 window_width = (uint16_t) GetScreenWidth(); 182 window_height = (uint16_t) GetScreenHeight(); 183 camera.offset.x = (float) window_width / 2; 184 camera.offset.y = (float) window_height / 2; 185 } 186 187 mouse = GetMousePosition(); 188 if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { 189 drag_mouse = mouse; 190 drag_target = camera.target; 191 drag = true; 192 } else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) { 193 drag = false; 194 } 195 196 mouse_scroll = GetMouseWheelMove(); 197 if (mouse_scroll != 0) { 198 wpos_prev = Vector2Transform(mouse, 199 MatrixInvert(GetCameraMatrix2D(camera))); 200 if (IsKeyDown(KEY_LEFT_SHIFT) && (tpu = in_tpu(wpos_prev))) { 201 info = tpu->user; 202 info->inst_off += mouse_scroll > 0 ? -1 : 1; 203 info->inst_off = MAX(0, MIN(info->inst_off, 204 (int) tpu->inst_cnt-1)); 205 } else { 206 camera.zoom *= mouse_scroll > 0 ? 2.f : 0.5f; 207 wpos = Vector2Transform(mouse, 208 MatrixInvert(GetCameraMatrix2D(camera))); 209 camera.target.x += wpos_prev.x - wpos.x; 210 camera.target.y += wpos_prev.y - wpos.y; 211 } 212 } 213 214 if (IsKeyDown(KEY_S) && GetTime() > last_step + 0.05) { 215 last_step = GetTime(); 216 tis_step(&tis); 217 } 218 219 if (drag) { 220 camera.target.x = drag_target.x 221 - (mouse.x - drag_mouse.x) / camera.zoom; 222 camera.target.y = drag_target.y 223 - (mouse.y - drag_mouse.y) / camera.zoom; 224 } 225 226 BeginDrawing(); 227 228 ClearBackground(BLACK); 229 230 BeginMode2D(camera); 231 232 for (tpu = tis.tpu_vec.tpus, i = 0; i < tis.tpu_vec.cnt; i++, tpu++) 233 draw_tpu(tpu); 234 235 EndMode2D(); 236 237 EndDrawing(); 238 } 239 240 tis_deinit(&tis); 241}