diff --git a/src/Demo/Lectures/MiniGrLib.ZC b/src/Demo/Lectures/MiniGrLib.ZC index af3c992f..a5ce5296 100755 --- a/src/Demo/Lectures/MiniGrLib.ZC +++ b/src/Demo/Lectures/MiniGrLib.ZC @@ -1,94 +1,136 @@ -#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, BLACK32, sizeof(image)); +} - 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); -} - 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; +U0 MGHLine(I64 x1, I64 x2, I64 y) +{//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) { F64 s, c, x1, y1, x2, y2; @@ -118,31 +160,34 @@ U0 MGCircle(I64 x, I64 y, F64 r) MGPlot(x+x1,y+y1); } } - - + 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. */ - // will flush screen VGA cache. + // will flush screen VGA cache and un-set framebuffer-busy bit. LFBFlush; } -MiniGrLibDemo; \ No newline at end of file +MiniGrLibDemo; diff --git a/src/Doc/ChangeLog.DD b/src/Doc/ChangeLog.DD index 20ba825f..dbcef2bd 100755 --- a/src/Doc/ChangeLog.DD +++ b/src/Doc/ChangeLog.DD @@ -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.