-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
139 lines (113 loc) · 3.44 KB
/
main.c
File metadata and controls
139 lines (113 loc) · 3.44 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <fcntl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "font8x8_basic.h"
struct framebuffer_context
{
struct fb_var_screeninfo info;
char* screen;
};
struct coordinates
{
unsigned int x;
unsigned int y;
};
int validate_coordinates(const struct fb_var_screeninfo info, const struct coordinates point)
{
if (point.x >= info.xres || point.y >= info.yres) return -1;
return 0;
}
static void set_pixel_in_framebuffer(const struct framebuffer_context* fb, const struct coordinates point)
{
const unsigned int bytes_per_line = fb->info.xres / 8;
const unsigned int mem_pos = point.y * bytes_per_line + point.x * fb->info.bits_per_pixel / 8;
const char value = 0x01 << point.x % 8;
fb->screen[mem_pos] |= value;
}
int set_pixel_value(const struct framebuffer_context* fb, const struct coordinates point)
{
if (validate_coordinates(fb->info, point) != 0) return -1;
set_pixel_in_framebuffer(fb, point);
return 0;
}
int draw_line(const struct framebuffer_context* fb, const struct coordinates start, const struct coordinates end)
{
//breBresenham's line algorithm
if (validate_coordinates(fb->info, start) != 0 || validate_coordinates(fb->info, end) != 0) return -1;
int dx = abs((int)end.x - (int)start.x);
int dy = abs((int)end.y - (int)start.y);
int sx = start.x < end.x ? 1 : -1;
int sy = start.y < end.y ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2;
int e2;
struct coordinates current_point = start;
while (1)
{
set_pixel_in_framebuffer(fb, current_point);
if (current_point.x == end.x && current_point.y == end.y) break;
e2 = err;
if (e2 > -dx)
{
err -= dy;
current_point.x += sx;
}
if (e2 < dy)
{
err += dx;
current_point.y += sy;
}
}
return 0;
}
int is_bit_set(char c, unsigned int bit)
{
return (c >> bit) & 1;
}
void draw_character(const struct framebuffer_context* fb, const struct coordinates offset,
unsigned int character_number)
{
struct coordinates bit_cordinates = {0, 0};
for (unsigned int y = 0; y < 8; y++)
{
bit_cordinates.y = offset.y + y;
for (unsigned int x = 0; x < 8; x++)
{
bit_cordinates.x = offset.x + x;
if (is_bit_set(font8x8_basic[character_number][y], x))
{
set_pixel_in_framebuffer(fb, bit_cordinates);
}
}
}
}
void draw_string(const struct framebuffer_context* fb, struct coordinates offset, const char* str)
{
const size_t size = strlen(str);
for (int i = 0; i < size; ++i)
{
draw_character(fb, offset, str[i]);
offset.x += 8;
}
}
int main()
{
int fb = open("/dev/fb0", O_RDWR);
struct framebuffer_context fb_ctx;
ioctl(fb, FBIOGET_VSCREENINFO, &fb_ctx.info);
printf("Screen: %dx%d\n", fb_ctx.info.xres, fb_ctx.info.yres);
unsigned int tamanho = fb_ctx.info.xres * fb_ctx.info.yres / 8;
fb_ctx.screen = (char*)mmap(0, tamanho, PROT_WRITE, MAP_SHARED, fb, 0);
struct coordinates point_a = {10, 10};
struct coordinates point_b = {118, 54};
struct coordinates invalid_point = {150, 50};
char str[] = "VolcanLab";
draw_string(&fb_ctx, point_a, str);
munmap(fb_ctx.screen, tamanho);
close(fb);
return 0;
}