revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-native / bootconsole / screen_fb.c
blob2d436225d43f3ef9c2b00e052d88554a74434382
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphical framebuffer console.
6 */
8 #include <bootconsole.h>
9 #include <string.h>
11 #include "console.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)
31 unsigned int len;
33 for (len = 0; len < scr_Width; len++)
35 if (s[len] == 0)
36 break;
39 return len;
42 /* Render a character at (xc, yc) */
43 static void RenderChar(unsigned char c, unsigned int xc, unsigned int yc)
45 unsigned int x, y;
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) */
53 if (c == '\0')
54 c = ' ';
56 /* Now render it on the screen */
57 for (y = 0; y < fontHeight; y++)
59 unsigned char in = *font++;
60 void *p = ptr;
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)
70 case 4:
71 *((int *)p) = val;
72 break;
74 case 3:
75 /* qemu's truecolor modes are known to be 3 bytes per pixel */
76 *((short *)p) = val;
77 *((char *)p + 2) = val;
78 break;
80 case 2:
81 *((short *)p) = val;
82 break;
84 case 1:
85 *((char *)p) = val;
86 break;
89 p += fb_BytesPerPix;
90 in <<= 1;
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;
102 fb_Resize(height);
105 void fb_Resize(unsigned int height)
107 scr_Height = height / fontHeight;
109 fb_Clear();
112 void fb_Clear(void)
114 void *ptr = scr_FrameBuffer;
115 unsigned int i;
117 /* Reset current position */
118 scr_XPos = 0;
119 scr_YPos = 0;
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 */
135 if (chr == 0)
136 return;
138 /* Reached end of line ? New line if so. */
139 if ((chr == '\n') || (scr_XPos >= scr_Width))
141 scr_XPos = 0;
142 scr_YPos++;
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;
151 unsigned int xc, yc;
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)
172 destLen = srcLen;
174 for (xc = 0; xc < destLen; xc++)
175 RenderChar(ptr[xc], xc, yc);
177 /* Go to the next line in fb_Mirror buffer */
178 ptr += scr_Width;
179 /* Source becomes destination */
180 destLen = srcLen;
183 /* Clear the bottom line */
184 for (xc = 0; xc < destLen; xc++)
185 RenderChar(0, xc, scr_YPos);
188 if (chr == '\n')
189 return;
191 /* Draw the character at current position and increment current column */
192 RenderChar(chr, scr_XPos++, scr_YPos);