1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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;
}
|