#include "gfx.h" #include "../game/motion.h" #include "../include/SDL.h" #include "../include/SDL_render.h" #include "../include/SDL_image.h" #include #include #include static Window window; static void draw_line_width(SDL_Renderer *r, point a, point b, float width) { // HACK: really bad way of drawing lines: draws width ^ 2 lines instead. // I should find a way to do it with OpenGL instead with basic mesh rendering. for (float i = 0; i < width; i += 1.f) { for (float j = 0; j < width; j += 1.f) { SDL_RenderDrawLine(r, (a.x - (width/2) + i), (a.y - (width/2) + j), (b.x - (width/2) + i), (b.y - (width/2) + j)); } } } errno_t init_gfx(bool funny) { if (SDL_Init(SDL_FLAGS) != 0) { printf("could not initialize sdl2\n"); exit(1); } if (IMG_Init(IMG_FLAGS) != IMG_FLAGS) { printf("could not initialize images\n"); exit(1); } window.window = SDL_CreateWindow("Auto Planner | 4388", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); window.surface = SDL_GetWindowSurface(window.window); window.renderer = SDL_CreateRenderer(window.window, -1, RENDER_FLAGS); if (window.renderer == NULL) { printf("could not create renderer\n"); exit(1); } window.texture = IMG_LoadTexture(window.renderer, funny ? "deeeen2.jpg" : "field.png"); if (window.texture == NULL) { printf("cannot find texture\n"); exit(1); } return 0; } void draw_field(Field *field) { SDL_SetRenderDrawColor(window.renderer, 0x18, 0x00, 0x00, 0xFF); SDL_RenderClear(window.renderer); int err = SDL_RenderCopy(window.renderer, window.texture, NULL, &(SDL_Rect) { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT }); if (err < 0) { printf("cannot copy texture\n"); exit(1); } } void draw_path(MotionPath *path, Field *field, bool bold, bool select) { if (path->odo_path == NULL) return; if (select) SDL_SetRenderDrawColor(window.renderer, 0x00, 0x00, 0xFF, 0xFF); else SDL_SetRenderDrawColor(window.renderer, 0xFF, 0x00, 0x00, 0xFF); double x = path->odo_path[0].x; double y = path->odo_path[0].y; for (int i = 1; i < path->len; i++) { double _x = path->odo_path[i].x; double _y = path->odo_path[i].y; point a = scale_to_screen( x, y, FIELD_RESCALED); point b = scale_to_screen(_x, _y, FIELD_RESCALED); draw_line_width(window.renderer, a, b, bold ? 6.f : 3.f); x = _x, y = _y; } } void draw_bezier(BezierPath *path, Field *field, bool bold, bool select) { if (path->arr == NULL && path->len > 0) return; if (select) SDL_SetRenderDrawColor(window.renderer, 0x00, 0x00, 0xFF, 0xFF); else SDL_SetRenderDrawColor(window.renderer, 0xFF, 0x00, 0x00, 0xFF); for (int i = 0; i < path->len-1; i += 2) { point prev = path->arr[i]; for (float j = 0; j < 1.f; j += RES) { point percent_a = lerp_point(path->arr[i ], path->arr[i + 1], j); point percent_b = lerp_point(path->arr[i + 1], path->arr[i + 2], j); point curve = lerp_point(percent_a, percent_b, j); point scaled_prev = scale_to_screen(prev.x, prev.y, FIELD_RESCALED); point scaled_curve = scale_to_screen(curve.x, curve.y, FIELD_RESCALED); draw_line_width(window.renderer, scaled_prev, scaled_curve, bold ? 6.f : 3.f); prev = curve; } } if (!select) return; for (int i = 0; i < path->len; i++) { point scaled_node = scale_to_screen(path->arr[i].x, path->arr[i].y, FIELD_RESCALED); if (path->selected == i) SDL_SetRenderDrawColor(window.renderer, 0x00, 0xFF, 0xFF, 0xFF); else SDL_SetRenderDrawColor(window.renderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderDrawRect(window.renderer, &(SDL_Rect) { scaled_node.x - 5, scaled_node.y - 5, 10, 10, }); } } void draw_robot(Field *field, point p) { const double size = .635; SDL_SetRenderDrawColor(window.renderer, 0xFF, 0xFF, 0xFF, 0xFF); point ll = scale_to_screen(p.x - size / 2, p.y - size / 2, FIELD_RESCALED); point rr = scale_to_screen(size, size, FIELD_RESCALED); point center = scale_to_screen(p.x, p.y, FIELD_RESCALED); SDL_RenderDrawPointF(window.renderer, center.x, center.y); SDL_RenderDrawRect(window.renderer, &(SDL_Rect) { .x = ll.x, .y = ll.y, .w = rr.x, .h = rr.y, }); } void blit_screen(void) { SDL_RenderPresent(window.renderer); }