summaryrefslogtreecommitdiff
path: root/src/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/screen.c b/src/screen.c
new file mode 100644
index 0000000..6f682ae
--- /dev/null
+++ b/src/screen.c
@@ -0,0 +1,98 @@
+#include <lib.h>
+#include <screen.h>
+#include <bochs.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define SCREEN_WIDTH 1024
+#define SCREEN_HEIGHT 768
+#define SCREEN_BIT_DEPTH 32
+
+struct rgb {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+};
+
+struct hsv {
+ uint16_t h;
+ uint16_t s;
+ uint16_t v;
+};
+
+static uint32_t *buffer = NULL;
+static uint32_t width, height;
+static uint8_t bit_depth;
+
+static uint16_t angle;
+
+static void set_pixel(struct rgb color, uint16_t x, uint16_t y) {
+ uint32_t offset = y * width + x;
+ buffer[offset] = (color.b << 0) | (color.g << 8) | (color.r << 16);
+}
+
+static float fmod(float f, float m) {
+ return f - (int)(f / m) * m;
+}
+
+static float fabs(float f) {
+ return f > 0 ? f : -f;
+}
+
+static struct rgb htor(struct hsv hsv) {
+ struct rgb rgb;
+ float s = hsv.s / 100.0;
+ float v = hsv.v / 100.0;
+ float c = s * v;
+ float x = c * (1-fabs(fmod(hsv.h/60.0, 2) - 1));
+ float m = v - c;
+ float r,g,b;
+
+ if (hsv.h < 60) {
+ r = c; g = x; b = 0;
+ } else if (hsv.h >= 60 && hsv.h < 120) {
+ r = x; g = c; b = 0;
+ } else if (hsv.h >= 120 && hsv.h < 180) {
+ r = 0; g = c; b = x;
+ } else if (hsv.h >= 180 && hsv.h < 240) {
+ r = 0; g = x; b = c;
+ } else if (hsv.h >= 240 && hsv.h < 300) {
+ r = x; g = 0; b = c;
+ } else {
+ r = c; g = 0; b = x;
+ }
+
+ rgb.r = (r + m) * 255;
+ rgb.g = (g + m) * 255;
+ rgb.b = (b + m) * 255;
+
+ return rgb;
+}
+
+static struct rgb get_color(uint16_t a, uint16_t x, uint16_t y) {
+ struct hsv hsv = {
+ .h = a,
+ .s = x * 100.0 / width,
+ .v = y * 100.0 / height,
+ };
+ return htor(hsv);
+}
+
+void screen_init(void) {
+ angle = 0;
+ width = SCREEN_WIDTH;
+ height = SCREEN_HEIGHT;
+ bit_depth = SCREEN_BIT_DEPTH;
+ buffer = bochs_init(width, height, bit_depth);
+}
+
+void screen_redraw(void) {
+ for (uint16_t y = 0; y < height; y++) {
+ for (uint16_t x = 0; x < width; x++) {
+ struct rgb color = get_color(angle, x, height - y);
+ set_pixel(color, x, y);
+ }
+ }
+ angle++;
+ angle %= 360;
+}