/*- * Copyright (C) 2025 Alessandro Iezzi * * This file is part of Tris Game. * * Tris Game is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Tris Game is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Tris Game. If not, see . */ #include #include #include #include #include "engine.h" #include "../util.h" #include "ui/ui.h" #include "../util/list.h" #ifdef X11 #include #endif #define RANGE_GL 2.0f static float xstep; static float ystep; static int width; static int height; static list_t *lines = NULL; typedef struct Line { int x1, y1, x2, y2; } Line; typedef struct Engine { UI *ui; void (*draw_frame)(); } Engine; static Engine *engine; /* FPS */ static time_t start; static int frames; static time_t end; void (*dispatch_ui_event)(int); void (*on_mouse_pressed)(); void engine_init(int w, int h) { engine = malloc(sizeof(Engine)); if (engine == NULL) { log_error("Error allocating memory for engine"); exit(EXIT_FAILURE); } width = w; height = h; engine->ui = ui_init(w, h); xstep = RANGE_GL / (float) w; ystep = RANGE_GL / (float) h; lines = list_create(); } static Line * engine_new_line(int x1, int y1, int x2, int y2) { Line *line = malloc(sizeof(Line)); line->x1 = x1; line->y1 = y1; line->x2 = x2; line->y2 = y2; return line; } void engine_draw_line(int x1, int y1, int x2, int y2) { if (lines != NULL) { Line *line = engine_new_line(x1, y1, x2, y2); list_add(lines, line); } } static void engine_calculate_fps() { frames ++; end = time(NULL); if (end - start >= 1.0) { printf("FPS: %d\n", frames); frames = 0; start = time(NULL); } } static void render_line(Line *line) { float _x1 = line->x1 * xstep - 1; float _y1 = (height - line->y1) * ystep - 1; float _x2 = line->x2 * xstep - 1; float _y2 = (height - line->y2) * ystep - 1; glVertex2f(_x1, _y1); glVertex2f(_x2, _y2); } static void draw_lines() { if (lines == NULL || lines->size <= 0) return; glLineWidth(5.0f); glBegin(GL_LINES); glColor3f(1.0f, 1.0f, 0.0f); /* Yellow */ list_node_t *current = lines->head; do { render_line((Line *) current->data); current = current->next; } while (current != NULL); glEnd(); } static void draw_frames() { glClearColor(0.0f, 0.0f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); draw_lines(); engine_calculate_fps(); } void engine_loop(void) { ui_set_loop_listener(draw_frames); /* FPS calculation */ start = time(NULL); frames = 0; ui_loop(); } void engine_on_mouse_pressed(void (*event)()) { on_mouse_pressed = event; } static void engine_dispatch_ui_events(int type) { int event_type = 0; switch (type) { #ifdef X11 case ButtonPress: event_type = ENGINE_MOUSE_PRESSED; if (on_mouse_pressed != NULL) { on_mouse_pressed(); } break; #endif default: event_type = 0; break; } dispatch_ui_event(event_type); } void engine_input(void (*f_input)(int engine_input)) { ui_set_generic_listener(engine_dispatch_ui_events); dispatch_ui_event = f_input; }