summaryrefslogtreecommitdiff
path: root/userspace/xterm/vesa.c
blob: 16c86494c726201d35e40cc578a67a39fff08541 (plain)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <malloc.h>
#include "vesa.h"

// framebuffer info
static uint32_t vesaXres;
static uint32_t vesaYres;
static uint32_t vesaPitch;
static uint32_t vesaBpp;
static uint32_t vesaAddr;

// font
static uint8_t *foolfont;
static uint32_t font_width;
static uint32_t font_height;

// cursor position
static int console_x;
static int console_y;

//terminal size
static int console_lines;
static int console_cols;

static uint8_t termdata[80*24];
static uint8_t termdata_bg[80*24];
static uint8_t termdata_fg[80*24];

void PutFont(char c, int x,int y, uint32_t color_fg,uint32_t color_bg);

// same colors as in screen.h
/*
static uint32_t cols[] = {
    0x0,      //black
    0x0066cc, //blue
    0x009900, //green
    0x33ffff, //cyan
    0xff3333, //red
    0xcc00cc, //magenta
    0x994c00, //brown
    0xa0a0a0, //light gray
    0x404040, //dark gray
    0x3399ff, //light blue
    0x99ff33, //light green
    0x99ffff, //cyan light
    0xff9999, //red light
    0xff99ff, //magenta light
    0xffff00, //yellow
    0xffffff, //white
};
*/

/** solarized theme */

static uint32_t cols[] = {
      0x073642,    //  S_base02 
      0xdc322f,    //  S_red    
      0x859900,    //  S_green  
      0xb58900,    //  S_yellow 
      0x268bd2,    //  S_blue   
      0xd33682,    //  S_magenta
      0x2aa198,    //  S_cyan   
      0xeee8d5,    //  S_base2  
      0x002b36,    //  S_base03 
      0xcb4b16,    //  S_orange 
      0x586e75,    //  S_base01 
      0x657b83,    //  S_base00 
      0x839496,    //  S_base0  
      0x6c71c4,    //  S_violet 
      0x93a1a1,    //  S_base1  
      0xfdf6e3,    //  S_base3  
};

/** update cursor position */
void vesa_update_cursor(uint32_t col,uint32_t row)
{
    int oldx=console_x;
    int oldy=console_y;

    console_x=col;
    console_y=row;

    vesa_console_put_char(termdata[oldy*80+oldx],termdata_bg[oldy*80+oldx],termdata_fg[oldy*80+oldx],oldx,oldy);
    vesa_console_put_char(termdata[row*80+col],termdata_bg[row*80+col],termdata_fg[row*80+col],col,row);
}

/** put char */
void vesa_console_put_char(uint8_t c,uint8_t color_bg, uint8_t color_fg, uint32_t x, uint32_t y)
{
    termdata[y*80+x]=c;
    termdata_bg[y*80+x]=color_bg;
    termdata_fg[y*80+x]=color_fg;

    if(x==console_x&&y==console_y)PutFont(c, x,y, cols[color_fg],cols[color_bg]);
    else PutFont(c, x,y, cols[color_bg],cols[color_fg]);
}
    
uint32_t vesa_init(int w,int h, int fb, char *fontname)
{
    // LOAD FONT
    FILE *f;
    if(fontname==NULL)f=fopen("/doc/fonts/envypn7x13.bin","r");
    else f=fopen("fontname","r");

    fread(&font_width,1,1,f);
    fread(&font_height,1,1,f);

    int bits_per_font=font_width*font_height;
    int alloc_bytes=(bits_per_font*95+7)/8;

    foolfont=malloc(alloc_bytes);
    fread(foolfont,1,alloc_bytes,f);

    // virtual screen
    vesaXres=w;
    vesaYres=h;

    vesaPitch=vesaXres*4;
    vesaBpp=4; //32bit
    vesaAddr=fb;//// TODOVMEM_USER_FRAMEBUFFER;
    
    //
    console_x=0;
    console_y=0;

    //TODO dynamic (but need to sync with terminal!)
    console_cols=80;
    console_lines=24;

    return vesaAddr;   
}

void PutPixel(int x,int y, uint32_t color)
{
    uint8_t *p=vesaAddr+y*vesaPitch+x*vesaBpp;
    uint32_t *pix=p;
    *pix=color;
}

static bool check_pixel(int idx,int x,int y)
{
    int pixel_index=idx*font_width*font_height+y*font_width+x;
    return foolfont[pixel_index/8]&(1<<(7-(pixel_index%8)));
}

/**
 * Put character C in column X of row Y using colors fg and bg
 */
void PutFont(char c, int x,int y, uint32_t color_fg,uint32_t color_bg)
{
    static uint8_t opac=0xbb;
    int fnt;
    if(c>=0x20&&c<=0x126)fnt=c-0x20;
    else return; // any other fonts??

    x=x*(font_width+1);
    y=y*(font_height+1);

    //fill broder with bg color
    for(int posx=x;posx<x+font_width+1;posx++)PutPixel(posx,y+font_height,color_bg|(opac<<24));
    for(int posy=y;posy<y+font_height;posy++)PutPixel(x+font_width,posy,color_bg|(opac<<24));

    // paint letter
    for(int posx=x;posx<x+font_width;posx++)
    {
        for(int posy=y;posy<y+font_height;posy++)
        {
            //if(deffont[fnt].line[posy-y]&1<<(7-(posx-x)))
            if(check_pixel(fnt,posx-x,posy-y))PutPixel(posx,posy,color_fg|(0xff<<24));
            else PutPixel(posx,posy,color_bg|(opac<<24));
        }
    }

    // invalidate area
    _gui_inval((x<<16)|(y),(font_width+1<<16)|(font_height+1),vesaAddr);

}