use the -newos toolchain even if -elf is present.
[newos.git] / apps / window_server / Renderer_vga.cpp
blob8bf77def02aefae2843a43087d23793103420435
1 #include "Renderer_vga.h"
2 #include "assert.h"
4 #define MIN(a, b) ((a) < (b) ? (a) : (b))
6 const unsigned char kCursorBits [] = {
7 0x3f,0x3f,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
8 0x3f,0x3f,0x3f,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
9 0xff,0x3f,0x3f,0x3f,0x3f,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
10 0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11 0xff,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
12 0xff,0xff,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,
13 0xff,0xff,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
14 0xff,0xff,0xff,0xff,0x3f,0x3f,0x3f,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
15 0xff,0xff,0xff,0xff,0x3f,0x3f,0x3f,0xff,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
16 0xff,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,
17 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xff,0xff,0xff,0xff,
18 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xff,0xff,0xff,
19 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xff,0xff,
20 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xff,
21 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xff,
22 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
25 Renderer_vga::Renderer_vga(char *baseAddress, int width, int height, int bytesPerRow)
26 : Renderer_8bpp(baseAddress, width, height, bytesPerRow)
28 fCursorX = width / 2;
29 fCursorY = height / 2;
30 DrawCursor();
33 const unsigned kBottom = 1;
34 const unsigned kTop = 2;
35 const unsigned kLeft = 4;
36 const unsigned kRight = 8;
38 #define clipmask(x, y, rect) \
39 ({ unsigned mask = 0; \
40 if (x < rect.left) mask |= kLeft; \
41 else if (x > rect.right) mask |= kRight; \
42 if (y < rect.top) mask |= kTop; \
43 else if (y > rect.bottom) mask |= kBottom; \
44 mask;})
46 inline int vert_intersection(int x1, int y1, int x2, int y2, int x)
48 return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
51 inline int horz_intersection(int x1, int y1, int x2, int y2, int y)
53 return x1 + (x2 - x1) * (y - y1) / (y2 - y1);
56 void Renderer_vga::DrawLine(int x1, int y1, int x2, int y2, char color)
58 Rect cursorRect(fCursorX, fCursorY, fCursorX + 16, fCursorY + 16);
59 bool invalidateCursor = true;
61 int clippedX1 = x1;
62 int clippedY1 = y1;
63 int clippedX2 = x2;
64 int clippedY2 = y2;
65 unsigned point1mask = clipmask(clippedX1, clippedY1, cursorRect);
66 unsigned point2mask = clipmask(clippedX2, clippedY2, cursorRect);
67 while (point1mask != 0 || point2mask != 0) {
68 if ((point1mask & point2mask) != 0) {
69 invalidateCursor = false;
70 break;
73 unsigned mask = point1mask ? point1mask : point2mask;
74 int x = 0;
75 int y = 0;
76 if (mask & kBottom) {
77 y = cursorRect.bottom;
78 x = horz_intersection(clippedX1, clippedY1, clippedX2, clippedY2, y);
79 } else if (mask & kTop) {
80 y = cursorRect.top;
81 x = horz_intersection(clippedX1, clippedY1, clippedX2, clippedY2, y);
82 } else if (mask & kRight) {
83 x = cursorRect.right;
84 y = vert_intersection(clippedX1, clippedY1, clippedX2, clippedY2, x);
85 } else if (mask & kLeft) {
86 x = cursorRect.left;
87 y = vert_intersection(clippedX1, clippedY1, clippedX2, clippedY2, x);
90 if (point1mask) {
91 // Clip point 1
92 point1mask = clipmask(x, y, cursorRect);
93 clippedX1 = x;
94 clippedY1 = y;
95 } else {
96 // Clip point 2
97 point2mask = clipmask(x, y, cursorRect);
98 clippedX2 = x;
99 clippedY2 = y;
103 if (invalidateCursor)
104 EraseCursor();
106 Renderer_8bpp::DrawLine(x1, y1, x2, y2, color);
108 if (invalidateCursor)
109 DrawCursor();
112 void Renderer_vga::FillRect(int x1, int y1, int x2, int y2, char color)
115 bool invalidateCursor = false;
116 if (Rect(x1, y1, x2, y2).Intersects(Rect(fCursorX, fCursorY, fCursorX + 16,
117 fCursorY + 16))) {
118 invalidateCursor = true;
119 EraseCursor();
122 Renderer_8bpp::FillRect(x1, y1, x2, y2, color);
123 if (invalidateCursor)
124 DrawCursor();
127 void Renderer_vga::Blit(int x, int y, char image[], int imageWidth,
128 int imageHeight, int imageBytesPerRow)
131 bool invalidateCursor = false;
132 if (Rect(x, y, x + imageWidth, y + imageHeight).Intersects(Rect(fCursorX,
133 fCursorY, fCursorX + 16, fCursorY + 16))) {
134 invalidateCursor = true;
135 EraseCursor();
138 Renderer_8bpp::Blit(x, y, image, imageWidth, imageHeight, imageBytesPerRow);
139 if (invalidateCursor)
140 DrawCursor();
143 void Renderer_vga::StretchBlit(const Rect &imageRect, const Rect &displayRect, char image[],
144 int imageBytesPerRow)
147 bool invalidateCursor = false;
148 if (displayRect.Intersects(Rect(fCursorX, fCursorY, fCursorX + 16,
149 fCursorY + 16))) {
150 invalidateCursor = true;
151 EraseCursor();
154 Renderer_8bpp::StretchBlit(imageRect, displayRect, image, imageBytesPerRow);
156 if (invalidateCursor)
157 DrawCursor();
160 void Renderer_vga::CopyRect(const Rect &source, const Rect &dest)
162 bool invalidateCursor = false;
163 Rect cursorRect(fCursorX, fCursorY, fCursorX + 16, fCursorY + 16);
164 if (cursorRect.Intersects(source) || cursorRect.Intersects(dest)) {
165 invalidateCursor = true;
166 EraseCursor();
169 Renderer_8bpp::CopyRect(source, dest);
170 if (invalidateCursor)
171 DrawCursor();
174 void Renderer_vga::SetCursorPosition(int x, int y)
176 EraseCursor();
177 fCursorX = x;
178 fCursorY = y;
179 DrawCursor();
182 void Renderer_vga::EraseCursor()
184 char *screen_ptr = BufferBaseAddress() + fCursorX + fCursorY * BufferBytesPerRow();
185 char *saveBackground = fSavedBackground;
186 int cursorDisplayWidth = MIN(16, BufferBytesPerRow() - fCursorX);
187 int cursorDisplayHeight = MIN(16, BufferHeight() - fCursorY);
188 int stride = BufferBytesPerRow() - cursorDisplayWidth;
190 for (int y = 0; y < cursorDisplayHeight; y++) {
191 for (int x = 0; x < cursorDisplayWidth; x++) {
192 if ((unsigned char) *saveBackground != 0xff)
193 *screen_ptr = *saveBackground;
195 screen_ptr++;
196 saveBackground++;
199 screen_ptr += stride;
200 saveBackground += 16 - cursorDisplayWidth;
204 void Renderer_vga::DrawCursor()
206 char *screen_ptr = BufferBaseAddress() + fCursorX + fCursorY * BufferBytesPerRow();
207 char *cursorImage = (char *) kCursorBits;
208 char *saveBackground = fSavedBackground;
209 int cursorDisplayWidth = MIN(16, BufferBytesPerRow() - fCursorX);
210 int cursorDisplayHeight = MIN(16, BufferHeight() - fCursorY);
211 int stride = BufferBytesPerRow() - cursorDisplayWidth;
213 for (int y = 0; y < cursorDisplayHeight; y++) {
214 for (int x = 0; x < cursorDisplayWidth; x++) {
215 if ((unsigned char) *cursorImage != 0xff) {
216 *saveBackground = *screen_ptr;
217 *screen_ptr = *cursorImage;
218 } else
219 *saveBackground = 0xff;
221 screen_ptr++;
222 cursorImage++;
223 saveBackground++;
226 screen_ptr += stride;
227 cursorImage += 16 - cursorDisplayWidth;
228 saveBackground += 16 - cursorDisplayWidth;