summaryrefslogtreecommitdiffstats
path: root/boot/limine/framebuffer.c
blob: 3758167ad79cb0b5e63cc22239073b76df6fdcd9 (plain) (blame)
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
#include "arch/x86_64/hal/obj.h"
#include "jove.h"
#include "lib/printf.h"
#include "limine.h"
#include "init.h"
#include "hal/framebuffer.h"

extern struct limine_framebuffer_response *_limine_framebuffers;

#define CHECK_IF_FB(obj) \
    if(obj_gettype(obj) != JOVE_OBJ_FRAMEBUFFER) { \
        reterr(EBADOBJ); \
    }

size_t
fb_width(jove_owned_obj_t *obj)
{
    CHECK_IF_FB(obj);
    struct limine_framebuffer *fb = obj_deref(obj);
    return fb->width;
}

size_t
fb_height(jove_owned_obj_t *obj)
{
    CHECK_IF_FB(obj);
    struct limine_framebuffer *fb = obj_deref(obj);
    return fb->height;
}

int
fb_blit(jove_owned_obj_t *obj,
        uint32_t *data,
        size_t x, size_t y,
        size_t width, size_t height)
{
    CHECK_IF_FB(obj);
    struct limine_framebuffer *fb = obj_deref(obj);
    
    uint32_t *fb_address = fb->address;
    for(size_t oline = 0; oline < height; oline++) {
        size_t line = oline + y;
        uint32_t *line_data = &data[oline * width];
        for(size_t ocol = 0; ocol < width; ocol++) {
            size_t col = ocol + x;
            fb_address[line * (fb->pitch >> 2) + col] = line_data[ocol];
        }
    }
    return 0;
}

void
fb_init()
{
    if(_limine_framebuffers->framebuffer_count == 0) {
        return;
    }
    struct limine_framebuffer *fb = _limine_framebuffers->framebuffers[0];
    size_t fb_bytes = fb->width * fb->height * (fb->bpp / 8);
    void *fb_virt = fb_remap((uintptr_t)fb->address, fb_bytes);

    //void *fb_virt = fb->address;
    if(fb_virt == NULL) {
        kprintf("Unable to remap framebuffer.\n");
        return;
    }

    kprintf("framebuffer: phys address %p\n", (uintptr_t)fb->address);
    kprintf("framebuffer: virt address %p\n", fb_virt);
    kprintf("framebuffer: width %ipx\n", fb->width);
    kprintf("framebuffer: height %ipx\n", fb->height);
    kprintf("framebuffer: %i bpp\n", fb->bpp);

    fb->address = fb_virt;
    {
        jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_FRAMEBUFFER_I);
        obj_settype(fb_obj, JOVE_OBJ_FRAMEBUFFER);
        obj_setvalue(fb_obj, (uintptr_t)fb);
        obj_release(fb_obj);
    }
}