2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Graphical framebuffer console.
8 #include <bootconsole.h>
14 * Framebuffer access can be extremely slow, so we use a mirror buffer.
15 * Our mirror is a monochrome text-mode representation of the screen.
16 * Unused positions are filled with zero bytes, this helps to determine
17 * line lengths for faster scrolling.
18 * These variables need to survive accross warm reboot, so we explicitly place them in .data section.
20 __attribute__((section(".data"))) char *fb_Mirror
= NULL
;
22 __attribute__((section(".data"))) static unsigned int fb_BytesPerLine
= 0; /* Bytes per line */
23 __attribute__((section(".data"))) static unsigned int fb_BytesPerPix
= 0; /* Bytes per pixel */
26 * Calculate length of current line in the fb_Mirror buffer.
27 * Similar to strlen() but takes into account maximum line length.
29 static unsigned int lineLen(const char *s
)
33 for (len
= 0; len
< scr_Width
; len
++)
42 /* Render a character at (xc, yc) */
43 static void RenderChar(unsigned char c
, unsigned int xc
, unsigned int yc
)
46 const unsigned char *font
= &fontData
[c
* fontHeight
];
47 void *ptr
= scr_FrameBuffer
+ fb_BytesPerLine
* yc
* fontHeight
+ fb_BytesPerPix
* xc
* fontWidth
;
49 /* Store our character in the mirror buffer */
50 fb_Mirror
[scr_Width
* yc
+ xc
] = c
;
52 /* Render zero bytes as spaces (do not depend on particular font) */
56 /* Now render it on the screen */
57 for (y
= 0; y
< fontHeight
; y
++)
59 unsigned char in
= *font
++;
62 for (x
= 0; x
< fontWidth
; x
++)
64 /* Get pixel from the font data */
65 int val
= (in
& 0x80) ? -1 : 0;
67 /* Draw the pixel. Do it in a single VRAM access, again to speed up */
68 switch (fb_BytesPerPix
)
75 /* qemu's truecolor modes are known to be 3 bytes per pixel */
77 *((char *)p
+ 2) = val
;
92 ptr
+= fb_BytesPerLine
;
96 void fb_Init(unsigned int width
, unsigned int height
, unsigned int depth
, unsigned int pitch
)
98 scr_Width
= width
/ fontWidth
;
99 fb_BytesPerPix
= depth
>> 3;
100 fb_BytesPerLine
= pitch
;
105 void fb_Resize(unsigned int height
)
107 scr_Height
= height
/ fontHeight
;
114 void *ptr
= scr_FrameBuffer
;
117 /* Reset current position */
121 /* Clear the framebuffer, line by line */
122 for (i
= 0; i
< scr_Height
* fontHeight
; i
++)
124 memset(ptr
, 0, fb_BytesPerPix
* scr_Width
* fontWidth
);
125 ptr
+= fb_BytesPerLine
;
128 /* Clear mirror buffer */
129 memset(fb_Mirror
, 0, scr_Width
* scr_Height
);
132 void fb_Putc(char chr
)
134 /* Ignore null bytes, they are output by formatting routines as terminators */
138 /* Reached end of line ? New line if so. */
139 if ((chr
== '\n') || (scr_XPos
>= scr_Width
))
145 if (scr_YPos
>= scr_Height
)
147 /* destLen contains length of line being erased */
148 unsigned int destLen
= lineLen(fb_Mirror
);
149 /* ptr contains address of line being scrolled */
150 char *ptr
= fb_Mirror
+ scr_Width
;
153 /* Reset line number */
154 scr_YPos
= scr_Height
- 1;
157 * Reprint the whole fb_Mirror (starting from the second line) at (0, 0).
158 * Update only used parts in order to speed up the scrolling.
160 for (yc
= 0; yc
< scr_YPos
; yc
++)
162 /* Calculate length of the line being scrolled */
163 unsigned int srcLen
= lineLen(ptr
);
166 * The next line (being reprinted on top ot the current one)
167 * must completely cover it, so we must copy a minimum of 'destLen' bytes.
168 * Mirror buffer contains zero bytes at unused positions, they will be
169 * rendered as blank spaces, erasing the previous text.
171 if (srcLen
> destLen
)
174 for (xc
= 0; xc
< destLen
; xc
++)
175 RenderChar(ptr
[xc
], xc
, yc
);
177 /* Go to the next line in fb_Mirror buffer */
179 /* Source becomes destination */
183 /* Clear the bottom line */
184 for (xc
= 0; xc
< destLen
; xc
++)
185 RenderChar(0, xc
, scr_YPos
);
191 /* Draw the character at current position and increment current column */
192 RenderChar(chr
, scr_XPos
++, scr_YPos
);