mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 10:26:59 +00:00
fun apps and inclusion of stb_image.h for future work
This commit is contained in:
185
src/kernel/userland/sort.c
Normal file
185
src/kernel/userland/sort.c
Normal file
@@ -0,0 +1,185 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
|
||||
#include "syscall.h"
|
||||
#include "libui.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#define WIN_W 400
|
||||
#define WIN_H 210
|
||||
#define NUM_ELEM (WIN_W / 2)
|
||||
#define BAR_W 2
|
||||
|
||||
static uint32_t *fb = NULL;
|
||||
static int heights[NUM_ELEM];
|
||||
static int moves = 0;
|
||||
|
||||
static unsigned long int next_rand = 1;
|
||||
|
||||
static int my_rand(void) {
|
||||
next_rand = next_rand * 1103515245 + 12345;
|
||||
return (unsigned int)(next_rand / 65536) % 32768;
|
||||
}
|
||||
|
||||
static void my_srand(unsigned int seed) {
|
||||
next_rand = seed;
|
||||
}
|
||||
|
||||
static void render_state(ui_window_t win) {
|
||||
// Clear fb
|
||||
for (int i = 0; i < WIN_W * WIN_H; i++) {
|
||||
fb[i] = 0xFF1E1E1E;
|
||||
}
|
||||
|
||||
// Draw bars
|
||||
for (int i = 0; i < NUM_ELEM; i++) {
|
||||
int h = heights[i];
|
||||
if (h > WIN_H - 10) h = WIN_H - 10;
|
||||
int x = i * BAR_W;
|
||||
int y = WIN_H - h;
|
||||
|
||||
// draw rect
|
||||
for (int yy = y; yy < WIN_H; yy++) {
|
||||
for (int xx = x; xx < x + BAR_W; xx++) {
|
||||
if (xx >= 0 && xx < WIN_W && yy >= 0 && yy < WIN_H) {
|
||||
fb[yy * WIN_W + xx] = 0xFF4A90E2; // Blue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Border for Box - bottom left
|
||||
int box_x = 10;
|
||||
int box_y = WIN_H - 40; // moved up by 10 pixels
|
||||
int box_w = 120;
|
||||
int box_h = 24;
|
||||
|
||||
for (int yy = box_y; yy < box_y + box_h; yy++) {
|
||||
for (int xx = box_x; xx < box_x + box_w; xx++) {
|
||||
if (xx == box_x || xx == box_x + box_w - 1 || yy == box_y || yy == box_y + box_h - 1) {
|
||||
fb[yy * WIN_W + xx] = 0xFFFFFFFF;
|
||||
} else {
|
||||
fb[yy * WIN_W + xx] = 0xFF1E1E1E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw framebuffer to window
|
||||
ui_draw_image(win, 0, 0, WIN_W, WIN_H, fb);
|
||||
|
||||
// Draw text inside the box
|
||||
char buf[32];
|
||||
strcpy(buf, "Moves: ");
|
||||
char num_buf[16];
|
||||
itoa(moves, num_buf);
|
||||
strcat(buf, num_buf);
|
||||
|
||||
ui_draw_string(win, box_x + 8, box_y + 4, buf, 0xFFFFFFFF);
|
||||
ui_mark_dirty(win, 0, 0, WIN_W, WIN_H);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
ui_window_t win = ui_window_create("sort", 100, 100, WIN_W, WIN_H);
|
||||
fb = (uint32_t*)malloc(WIN_W * WIN_H * sizeof(uint32_t));
|
||||
if (!fb) return 1;
|
||||
|
||||
// Seed PRNG with system time (ticks)
|
||||
my_srand((unsigned int)sys_system(16, 0, 0, 0, 0));
|
||||
|
||||
// Initialize perfect slope
|
||||
int max_h = WIN_H - 40; // max height
|
||||
int min_h = 10;
|
||||
for (int i = 0; i < NUM_ELEM; i++) {
|
||||
heights[i] = min_h + (max_h - min_h) * i / (NUM_ELEM - 1);
|
||||
}
|
||||
|
||||
// Shuffle
|
||||
for (int i = NUM_ELEM - 1; i > 0; i--) {
|
||||
int j = my_rand() % (i + 1);
|
||||
int t = heights[i];
|
||||
heights[i] = heights[j];
|
||||
heights[j] = t;
|
||||
}
|
||||
|
||||
gui_event_t ev;
|
||||
|
||||
// Cocktail shaker sort variables
|
||||
bool swapped = true;
|
||||
int start = 0;
|
||||
int end = NUM_ELEM - 1;
|
||||
bool done = false;
|
||||
|
||||
// We render after each swap so the steps are extremely visual
|
||||
while (1) {
|
||||
if (ui_get_event(win, &ev)) {
|
||||
if (ev.type == GUI_EVENT_CLOSE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
swapped = false;
|
||||
|
||||
// Forward pass
|
||||
for (int i = start; i < end; ++i) {
|
||||
if (heights[i] > heights[i + 1]) {
|
||||
int t = heights[i];
|
||||
heights[i] = heights[i+1];
|
||||
heights[i+1] = t;
|
||||
swapped = true;
|
||||
moves++;
|
||||
|
||||
render_state(win);
|
||||
|
||||
// Allow UI events while sorting
|
||||
if (ui_get_event(win, &ev)) {
|
||||
if (ev.type == GUI_EVENT_CLOSE) {
|
||||
goto exit_app;
|
||||
}
|
||||
}
|
||||
// No explicit sleep, rendering takes some time and provides natural visual delay.
|
||||
// If it's too fast, we'll add sleep(1) here later.
|
||||
}
|
||||
}
|
||||
|
||||
if (!swapped) {
|
||||
done = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
swapped = false;
|
||||
end = end - 1;
|
||||
|
||||
// Backward pass
|
||||
for (int i = end - 1; i >= start; --i) {
|
||||
if (heights[i] > heights[i + 1]) {
|
||||
int t = heights[i];
|
||||
heights[i] = heights[i+1];
|
||||
heights[i+1] = t;
|
||||
swapped = true;
|
||||
moves++;
|
||||
|
||||
render_state(win);
|
||||
|
||||
// Allow UI events
|
||||
if (ui_get_event(win, &ev)) {
|
||||
if (ev.type == GUI_EVENT_CLOSE) {
|
||||
goto exit_app;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
start = start + 1;
|
||||
} else {
|
||||
// Sort is done, just render and idle
|
||||
render_state(win);
|
||||
sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
exit_app:
|
||||
free(fb);
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user