mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-25 23:10:32 +00:00
Rewrote MiniGrLib, fixes #40.
This commit is contained in:
parent
87c6e59179
commit
86a390d9c6
2 changed files with 120 additions and 72 deletions
|
@ -1,92 +1,134 @@
|
|||
#define VGAP_IDX 0x3C4
|
||||
#define VGAP_DATA 0x3C5
|
||||
#define VGAR_MAP_MASK 0x02
|
||||
|
||||
U8 rev[256], //The VGA bits are backward
|
||||
image[640 * 480 / 8]; //We need read-modify write.
|
||||
//0xA0000 alias memory can't be read.
|
||||
U32 image[GR_HEIGHT * GR_WIDTH];
|
||||
|
||||
U0 MGInit()
|
||||
{
|
||||
I64 i, j;
|
||||
|
||||
MemSet(image, 0, sizeof(image));
|
||||
MemSet(rev, 0, sizeof(rev));
|
||||
for (i = 0; i < 256; i++)
|
||||
for (j = 0; j < 8; j++)
|
||||
if (Bt(&i, j))
|
||||
Bts(&rev[i], 7 - j);
|
||||
MemSet(image, BLACK32, sizeof(image));
|
||||
}
|
||||
|
||||
U0 MGUpdate()
|
||||
{//Copy image to VGA memory
|
||||
{//Copy image to framebuffer memory
|
||||
//For better performance we could only write what's changed.
|
||||
//0xA0000 alias is slower than normal RAM.
|
||||
OutU8(VGAP_IDX, VGAR_MAP_MASK);
|
||||
OutU8(VGAP_DATA, 0xF);//All color planes at once -- Black and White
|
||||
MemCopy(text.vga_alias, image,sizeof(image)); //Alias of 0xA0000
|
||||
MemCopy(text.fb_alias, image, sizeof(image));
|
||||
}
|
||||
|
||||
U0 MGPlot(I64 x,I64 y)
|
||||
{
|
||||
if (0 <= x < 640 && 0 <= y < 480)
|
||||
Bts(image,y * 640 + x ^ 7);
|
||||
if (0 <= x < GR_WIDTH && 0 <= y < GR_HEIGHT)
|
||||
image[x + y * GR_WIDTH] = WHITE32;
|
||||
}
|
||||
|
||||
U0 MGHLine(I64 x1, I64 x2, I64 y)
|
||||
{//Warning! No clipping
|
||||
//For performance, we do as many whole-bytes as possible.
|
||||
U8 *ptr;
|
||||
I64 i, w, leading, trailing, whole_bytes;
|
||||
{//No clipping
|
||||
I64 x;
|
||||
|
||||
if (y >= GR_HEIGHT)
|
||||
return;
|
||||
if (x2 < x1)
|
||||
SwapI64(&x1, &x2);
|
||||
ptr = image + y * 640 / 8 + x1 >> 3;
|
||||
w = x2 - x1 + 1;
|
||||
leading = 8 - x1 & 7;
|
||||
trailing = (x2 + 1) & 7;
|
||||
if (leading + trailing > w)
|
||||
*ptr |= rev[(0xFF00 >> leading & (0x00FF << trailing) >> 8)];
|
||||
else
|
||||
if (x1 < 0)
|
||||
x1 = 0;
|
||||
if (x2 < x1)
|
||||
SwapI64(&x1, &x2);
|
||||
x = x1;
|
||||
|
||||
while (x <= x2 && x < GR_WIDTH)
|
||||
{
|
||||
whole_bytes = (w - leading - trailing) >> 3;
|
||||
if (leading)
|
||||
*ptr++ |= rev[(0xFF00 >> leading) & 0xFF];
|
||||
for (i = 0; i < whole_bytes; i++)
|
||||
*ptr++ = 0xFF;
|
||||
if (trailing)
|
||||
*ptr++ |= rev[(0x00FF << trailing) >> 8];
|
||||
image[x + y * GR_WIDTH] = WHITE32;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
U0 MGLine(I64 x1,I64 y1,I64 x2,I64 y2)
|
||||
{//Warning! No clipping
|
||||
I64 dx=x2-x1,dy=y2-y1;
|
||||
{//No clipping
|
||||
I64 x_start, x_end, y_start, y_end, x, y, dx, dy, c;
|
||||
|
||||
x1 <<= 32; x2 <<= 32;
|
||||
y1 <<= 32; y2 <<= 32;
|
||||
if (AbsI64(dx) > AbsI64(dy))
|
||||
c = 0;
|
||||
x_start = MinI64(x1, x2);
|
||||
|
||||
if (x_start == x1)
|
||||
{
|
||||
dy = dy << 32 / AbsI64(dx);
|
||||
dx = SignI64(dx) << 32;
|
||||
while (x1 != x2)
|
||||
y_start = y1;
|
||||
x_end = x2;
|
||||
y_end = y2;
|
||||
}
|
||||
else // x2
|
||||
{
|
||||
y_start = y2;
|
||||
x_end = x1;
|
||||
y_end = y1;
|
||||
}
|
||||
|
||||
x = x_start;
|
||||
y = y_start;
|
||||
dx = x_end - x_start;
|
||||
|
||||
if (y_end < y_start)
|
||||
{
|
||||
dy = y_start - y_end;
|
||||
|
||||
if (dx >= dy)
|
||||
{
|
||||
MGPlot(x1.i32[1], y1.i32[1]);
|
||||
x1 += dx; y1 += dy;
|
||||
while (x <= x_end)
|
||||
{
|
||||
MGPlot(x, y);
|
||||
c += dy;
|
||||
if (c >= dx)
|
||||
{
|
||||
c -= dx;
|
||||
y--;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (y > y_end)
|
||||
{
|
||||
MGPlot(x, y);
|
||||
c += dx;
|
||||
if (c >= dy)
|
||||
{
|
||||
c -= dy;
|
||||
x++;
|
||||
}
|
||||
y--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = dx << 32 / AbsI64(dy);
|
||||
dy = SignI64(dy) << 32;
|
||||
while (y1 != y2)
|
||||
dy = y_end - y_start;
|
||||
|
||||
if (dx >= dy)
|
||||
{
|
||||
MGPlot(x1.i32[1], y1.i32[1]);
|
||||
x1 += dx;
|
||||
y1 += dy;
|
||||
while (x <= x_end)
|
||||
{
|
||||
MGPlot(x, y);
|
||||
c += dy;
|
||||
if (c >= dx)
|
||||
{
|
||||
c -= dx;
|
||||
y++;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (y <= y_end)
|
||||
{
|
||||
MGPlot(x, y);
|
||||
c += dx;
|
||||
if (c >= dy)
|
||||
{
|
||||
c -= dy;
|
||||
x++;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
MGPlot(x1.i32[1], y1.i32[1]);
|
||||
}
|
||||
|
||||
U0 MGCircle(I64 x, I64 y, F64 r)
|
||||
|
@ -119,29 +161,32 @@ U0 MGCircle(I64 x, I64 y, F64 r)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
U0 MiniGrLibDemo()
|
||||
{
|
||||
I64 i;
|
||||
|
||||
MGInit;
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
MGHLine(200 + i, 400 + i, 300 + i);
|
||||
MGHLine(200 + i, 400 + i, 400 + i);
|
||||
|
||||
for (i = 0; i < 500; i += 10)
|
||||
MGLine(i, 0, 0, 480 - i);
|
||||
for (i = 0; i < GR_HEIGHT + 20; i += 10)
|
||||
MGLine(i, 0, 0, GR_HEIGHT - i);
|
||||
|
||||
for (i = 0; i < 300; i += 4)
|
||||
MGCircle(200, 100 + i, i);
|
||||
MGCircle(400, 200 + i, i);
|
||||
|
||||
MGUpdate;
|
||||
Busy(1500000);
|
||||
|
||||
|
||||
/*
|
||||
We are returning graphics to normal operations under ZealOS.
|
||||
It is not normal to by-pass the ZealOS graphcis routines.
|
||||
The ZealOS graphics don't know VGA has changed.
|
||||
This bit tells ZealOS to update whole screen.
|
||||
The ZealOS graphics don't know the framebuffer has changed.
|
||||
This function tells ZealOS to update whole screen.
|
||||
*/
|
||||
//<CTRL-ALT-v> will flush screen VGA cache.
|
||||
//<CTRL-ALT-v> will flush screen VGA cache and un-set framebuffer-busy bit.
|
||||
LFBFlush;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
$WW,1$$FG,5$$TX+CX,"ChangeLog"$$FG$
|
||||
$IV,1$----03/17/23 17:44:24----$IV,0$
|
||||
* Rewrote $LK+PU,"MiniGrLib",A="FI:::/Demo/Lectures/MiniGrLib.ZC"$, replaced old VGA-specific code to work with 32-bit framebuffer.
|
||||
|
||||
$IV,1$----03/14/23 03:23:46----$IV,0$
|
||||
* Created %o Bool $LK+PU,"StrPrint",A="FF:::/Kernel/StrPrint.ZC,'o':"$ format code, updated $LK+PU,"Print.DD",A="FI:::/Doc/Print.DD"$ with new %o code and previously undocumented format codes.
|
||||
|
||||
|
|
Loading…
Reference in a new issue