sav

Sorting Algorithms Visualized
Index Commits Files Refs README LICENSE
commit 5689e041486857536336d303c694e2afb9c1f3f7
parent e2906963e3d9eab289c9862128a6f1d33bccc5fa
Author: mjkloeckner <martin.cachari@gmail.com>
Date:   Sun, 31 Jul 2022 23:19:04 -0300

FPS control and general code improvement

Diffstat:
Marray.h | 6+++---
Mdrw.c | 26+++++++++++++-------------
Mdrw.h | 2+-
Mmain.c | 51++++++++++++++++++++++++++++++++++++---------------
Msav.c | 9++++++---
Msav.h | 5++++-
Msdl_extra.c | 13+++++--------
Msdl_extra.h | 6+++---
Msort.c | 5++---
Msort.h | 5+----
Mutil.h | 1-
11 files changed, 74 insertions(+), 55 deletions(-)
diff --git a/array.h b/array.h
@@ -15,15 +15,15 @@ typedef enum {
 } shuffle_t;
 
 typedef struct _Arr {
-    int *v;
-    int *bk;
+    int *v;  /* array to be sorted */
+    int *bk; /* copy of the array to be sorted */
     size_t len;
     shuffle_t shuffle_sel;
     void (*shuffle)(struct _Arr *arr);
 } Arr;
 
 static char *const shuffle_t_str[MAX_SHUFFLE] = {
-    "in_order",
+    "in order",
     "reversed",
     "random",
 };
diff --git a/drw.c b/drw.c
@@ -38,30 +38,30 @@ static status_t drw_status_bar_fetch_text(Drw *drw, SAV *sav) {
 
     if(sav->status == WELCOME) {
         snprintf(drw->bar_text, drw->bar_text_len - 2,
-                "  Welcome to sorting algorithms visualized  [%s] [%-25s   press SPACE to start sorting",
+                "  Welcome to sorting algorithms visualized  [%s] [%-15s  press SPACE to start sorting",
                 shuffle_t_str[sav->arr->shuffle_sel], algo_sel_str[sav->sort_algo]);
     }
     else if(sav->status == START) {
         snprintf(drw->bar_text, drw->bar_text_len - 2,
-                "  %-8s  [%s] [%-25s   press SPACE to start sorting", sort_status_str[OK],
+                "  %-8s  [%s] [%-15s  press SPACE to start sorting", sort_status_str[OK],
                 shuffle_t_str[sav->arr->shuffle_sel], algo_sel_str[sav->sort_algo]);
     }
     else if(sav->status == RUN) {
         if(sav->sort_status == PAUSE)
             snprintf(drw->bar_text, drw->bar_text_len - 2,
-                    "  %-8s  [%s] [%-25s   L: %ld, C: %ld, S: %ld   Press SPACE to resume",
+                    "  %-8s  [%s] [%-15s  L:%ld C:%ld S:%ld",
                     sort_status_str[sav->sort_status],
                     shuffle_t_str[sav->arr->shuffle_sel], algo_sel_str[sav->sort_algo],
                     sav->arr->len, sav->cmps, sav->swps);
         else if(sav->sort_status == SORTED)
             snprintf(drw->bar_text, drw->bar_text_len - 2,
-                    "  %-8s  [%s] [%-25s   L: %ld, C: %ld, S: %ld, done in %lds, extra storage used: %ld Bytes",
+                    "  %-8s  [%s] [%-15s  L:%ld C:%ld S:%ld, done in %lds, extra storage: %ldB",
                     sort_status_str[sav->sort_status],
                     shuffle_t_str[sav->arr->shuffle_sel], algo_sel_str[sav->sort_algo],
                     sav->arr->len, sav->cmps, sav->swps, (sav->tf - sav->ti), sav->B_used);
         else if(sav->sort_status == RUN)
             snprintf(drw->bar_text, drw->bar_text_len - 2,
-                    "  %-8s  [%s] [%-25s   L: %ld, C: %ld, S: %ld", sort_status_str[sav->sort_status],
+                    "  %-8s  [%s] [%-15s  L:%ld C:%ld S:%ld", sort_status_str[sav->sort_status],
                     shuffle_t_str[sav->arr->shuffle_sel], algo_sel_str[sav->sort_algo],
                     sav->arr->len, sav->cmps, sav->swps);
     }
@@ -113,21 +113,21 @@ status_t drw_status_bar(Drw *drw, SAV *sav) {
 }
 
 status_t Drw_create(Drw **drw) {
-    SDL_Renderer *rend = NULL;
-    SDL_Window *win = NULL;
     TTF_Font *font = NULL;
     status_t st;
 
-    if(((*drw) = (Drw *)malloc(sizeof(Drw))) == NULL) return ERROR_MEMORY_ALLOC;
+    if(((*drw) = (Drw *)malloc(sizeof(Drw))) == NULL)
+        return ERROR_MEMORY_ALLOC;
+
     memset(*drw, 0, sizeof(Drw));
 
-    if((st = SDL_setup(&win, &rend)) != OK) return st;
+    if((st = SDL_setup(&(*drw)->win, &(*drw)->rend)) != OK)
+        return st;
 
     font = TTF_OpenFont(FONT_NAME, FONT_SIZE);
-    if(font == NULL) return ERROR_TTF_OPENING_FONT;
+    if(font == NULL)
+        return ERROR_TTF_OPENING_FONT;
 
-    (*drw)->rend = rend;
-    (*drw)->win = win;
     (*drw)->font = font;
     (*drw)->font_size = FONT_SIZE;
     (*drw)->bar_border = 2;
@@ -138,7 +138,7 @@ status_t Drw_create(Drw **drw) {
     (*drw)->text_color.g = (char)(FONT_COLOR >> 8) & 0xFF;
     (*drw)->text_color.b = (char)(FONT_COLOR) & 0xFF;
 
-    SDL_GetWindowSize(win, &((*drw)->w), &((*drw)->h));
+    SDL_GetWindowSize((*drw)->win, &((*drw)->w), &((*drw)->h));
 
     (*drw)->bar_rect.x = (*drw)->bar_border; /* top left + x */
     (*drw)->bar_rect.y = (*drw)->h - (*drw)->bar_border; /* top left + y, (y < 0) */
diff --git a/drw.h b/drw.h
@@ -17,7 +17,7 @@
 #define FONT_NAME    "/home/mk/.local/share/fonts/VictorMono-Bold.ttf"
 #define FONT_COLOR    0xBBBBBB
 
-#define BAR_HEIGHT    14
+#define BAR_HEIGHT    15
 
 #define WIN_MIN_W    800
 #define WIN_MIN_H    600
diff --git a/main.c b/main.c
@@ -1,7 +1,3 @@
-#include <stdio.h>
-#include <pthread.h>
-#include <assert.h>
-
 #include "sav.h"
 #include "drw.h"
 #include "sort.h"
@@ -9,6 +5,11 @@
 #include "sdl_extra.h"
 #include "array.h"
 
+#include <stdio.h>
+#include <pthread.h>
+#include <assert.h>
+
+#define SHOW_FPS true
 #define WELCOME_MSG_TIME 3
 
 void check_events(Drw *, SAV *);
@@ -16,8 +17,8 @@ void check_events(Drw *, SAV *);
 /* pthread_create compliant start routine */
 void *routine_wrapper(void *);
 
-static void (*sort_handler[ALGORITHMS_COUNT])(SAV *) = {
-    &bubble_sort,
+static void (*sort_handler[])(SAV *) = {
+    /* &bubble_sort, */
     &bubble_sort_improved,
     &insertion_sort,
     &merge_sort_wrapper,
@@ -27,8 +28,7 @@ static void (*sort_handler[ALGORITHMS_COUNT])(SAV *) = {
     &heap_sort
 };
 
-void *routine_wrapper(void *arg)
-{
+void *routine_wrapper(void *arg) {
     SAV *sav = (SAV *)arg;
 
     assert((sav->sort_algo != ALGORITHMS_COUNT) && "Default sorting algorithm not set");
@@ -38,16 +38,18 @@ void *routine_wrapper(void *arg)
     return NULL;
 }
 
-/* TODO: Random, reversed, in_order arrays selector from GUI */
 /* TODO: Support command line arguments */
 /* TODO: Support sound */
 /* TODO: More sorting algorithms */
+/* TODO: add sav methods */
 
 int main (void)
 {
     SAV *sav = NULL;
     Drw *drw = NULL;
     time_t tic, toc;
+    unsigned int ti, tf, dt;
+    short time_per_frame;
 
     pthread_t p1 = 0;
     status_t st;
@@ -55,17 +57,22 @@ int main (void)
     if((st = SAV_create(&sav)) != OK) goto end;
     if((st = Drw_create(&drw)) != OK) goto end;
 
-    /* defaults */
-    sav->sort_algo = INSERTION_SORT;
-    sav->arr->shuffle_sel = RANDOM;
-    sav->status = WELCOME;
-    sav->sort_status = PAUSE;
     tic = time(NULL);
-
+    time_per_frame = 16; /* miliseconds */
     arr_shuffle(sav->arr);
 
+#if SHOW_FPS
+    short fps = 0;
+#endif
+
     /* main loop */
+    dt = ti = tf = 0;
     while(sav->status != STOP) {
+        if(!ti) ti = SDL_GetTicks();
+        else dt = tf - ti; /* how many ms for a frame */
+
+        /* printf("DT: %d | TI: %d | TF: %d\n", dt, ti, tf); */
+
         check_events(drw, sav);
 
         SDL_SetRenderDrawColor(drw->rend, 29, 28, 28, 0);
@@ -105,6 +112,20 @@ int main (void)
             pthread_join(p1, NULL);
             sav->sel = sav->cmp = ARR_LEN + 1;
         }
+
+        /* if less than `time_per_frame`, delay */
+        if(dt <= time_per_frame)
+            SDL_Delay(time_per_frame - dt);
+
+#if SHOW_FPS
+        if(dt > time_per_frame)
+            fps = 1000 / dt;
+
+        printf("FPS is: %i\n", fps);
+#endif
+
+        ti = tf;
+        tf = SDL_GetTicks();
     }
 
 end:
diff --git a/sav.c b/sav.c
@@ -17,14 +17,17 @@ status_t SAV_create(SAV **sav) {
     (*sav)->sel = (*sav)->cmp = ARR_MAX + 1;
     (*sav)->cmps = (*sav)->swps = (*sav)->its = (*sav)->B_used = 0;
 
-    (*sav)->status = RUN;
+    /* defaults */
+    (*sav)->status = WELCOME;
     (*sav)->sort_status = PAUSE;
-    (*sav)->sort_algo = ALGORITHMS_COUNT;
-    (*sav)->sort_delay = SORT_DELAY_DEFAULT;
+    (*sav)->sort_algo = INSERTION_SORT;
+    (*sav)->sort_delay = SAV_DEFAULT_SORT_DELAY;
 
     if((st = Arr_create(&(*sav)->arr)) != OK)
         return st;
 
+    (*sav)->arr->shuffle_sel = RANDOM;
+
     return OK;
 }
 
diff --git a/sav.h b/sav.h
@@ -7,8 +7,11 @@
 #include "util.h"
 #include "array.h"
 
+#define SAV_DEFAULT_SORT_DELAY        5
+#define SAV_SORT_DELAY_MAX  500
+
 typedef enum {
-    BUBBLE_SORT,
+    /* BUBBLE_SORT, */
     BUBBLE_SORT_IMPROVED,
     INSERTION_SORT,
     MERGE_SORT,
diff --git a/sdl_extra.c b/sdl_extra.c
@@ -15,16 +15,13 @@ status_t SDL_setup(SDL_Window **win, SDL_Renderer **rend) {
         SDL_WINDOW_RESIZABLE
     );
 
-    *rend = SDL_CreateRenderer(*win, -1, SDL_RENDERER_ACCELERATED);
+    *rend = SDL_CreateRenderer(*win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
 
-    if ((*win == NULL) || (rend == NULL))
+    if ((*win == NULL) || (*rend == NULL))
         return ERROR_NULL_POINTER;
-    else if(TTF_Init() == -1)
-        return ERROR_SDL_FONT_INIT;
 
-    SDL_SetRenderDrawColor(*rend, 32, 32, 32, 0);
-    SDL_RenderClear(*rend);
-    SDL_RenderPresent(*rend);
+    if(TTF_Init() == -1)
+        return ERROR_SDL_FONT_INIT;
 
     /* compute the window minimum size */
     min_w = ((ARR_LEN * RECT_WIDTH) + (2 * X_BORDER));
@@ -39,9 +36,9 @@ status_t SDL_cleanup(SDL_Window *win, SDL_Renderer *rend) {
     if((win == NULL) || (rend == NULL))
         return ERROR_NULL_POINTER;
 
+    TTF_Quit();
     SDL_DestroyRenderer(rend);
     SDL_DestroyWindow(win);
-    TTF_Quit();
     SDL_Quit();
     return OK;
 }
diff --git a/sdl_extra.h b/sdl_extra.h
@@ -1,12 +1,12 @@
 #ifndef __SDL_EXTRA_H__
 #define __SDL_EXTRA_H__
 
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_ttf.h>
-
 #include "array.h"
 #include "status.h"
 
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+
 #define X_BORDER    40
 #define Y_BORDER    40
 #define TOP_BORDER    50
diff --git a/sort.c b/sort.c
@@ -8,7 +8,7 @@
 void set_sort_speed(SAV *sav, size_t new_value) {
     if(sav == NULL) return;
 
-    if((new_value > 0) && (new_value <= SORT_DELAY_MAX)) {
+    if((new_value > 0) && (new_value <= SAV_SORT_DELAY_MAX)) {
         printf("INFO: Updating sort_delay to: %ld\n", new_value);
         sav->sort_delay = new_value;
     }
@@ -363,9 +363,8 @@ void heap_sort(SAV *sav) {
     sav->ti = time(NULL);
 
     /* Build max heap */
-    for (i = ((sav->arr->len / 2) - 1); i >= 0; i--) {
+    for (i = ((sav->arr->len / 2) - 1); i >= 0; i--)
         heapify(sav, sav->arr->len, i);
-    }
 
     /* Heap sort */
     for (i = (sav->arr->len - 1); i >= 0; i--) {
diff --git a/sort.h b/sort.h
@@ -3,12 +3,9 @@
 
 #include "sav.h"
 
-#define SORT_DELAY_DEFAULT  5
-#define SORT_DELAY_MAX      250
-
 static char * const algo_sel_str[ALGORITHMS_COUNT + 1] = {
+    /* "bubble sort]", */
     "bubble sort]",
-    "improved bubble sort]",
     "insertion sort]",
     "merge sort]",
     "quick sort]",
diff --git a/util.h b/util.h
@@ -11,6 +11,5 @@
 
 void end(const char *msg);
 void swap(int *a, int *b);
-void wait_main_thread(status_t *st);
 
 #endif // __UTIL_H__