Fork of David Smart's RA8875 library

Fork of RA8875 by David Smart

Revision:
41:2956a0a221e5
Parent:
40:04aa280dfa39
Child:
42:7cbdfd2bbfc5
--- a/GraphicsDisplay.cpp	Tue Feb 04 02:58:06 2014 +0000
+++ b/GraphicsDisplay.cpp	Sat Feb 08 17:35:45 2014 +0000
@@ -8,10 +8,6 @@
 #include "GraphicsDisplay.h"
 #include "Bitmap.h"
 
-// Defining USE_HW causes compilation of code that uses hardware drawing
-// provided by the super-class.
-#define USE_HW
-
 #define DEBUG "GD"
 // ...
 // INFO("Stuff to show %d", var); // new-line is automatically appended
@@ -219,17 +215,7 @@
 
 void GraphicsDisplay::fill(int x, int y, int w, int h, color_t color)
 {
-    #ifdef USE_HW
     fillrect(x,y, x+w, y+h, color);
-    #else
-    window(x, y, w, h);
-    _StartGraphicsStream();
-    for(int i=0; i<w*h; i++) {
-        putp(color);
-    }
-    _EndGraphicsStream();
-    WindowMax();
-    #endif
 }
 
 RetCode_t GraphicsDisplay::cls()
@@ -323,6 +309,109 @@
     return c;
 }
 
+/// RRRR RGGG GGGB BBBB
+RGBQUAD GraphicsDisplay::RGB16ToRGBQuad(color_t c)
+{
+    RGBQUAD q;
+    
+    memset(&q, 0, sizeof(q));
+    q.rgbBlue  = (c & 0x001F) << 3;      /* Blue value */
+    q.rgbGreen = (c & 0x07E0) >> 3;      /* Green value */
+    q.rgbRed   = (c & 0xF800) >> 8;      /* Red value */
+    q.rgbReserved = 0;
+    return q;
+}
+
+
+RetCode_t GraphicsDisplay::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP)
+{
+    BITMAPFILEHEADER BMP_Header;
+    BITMAPINFOHEADER BMP_Info;
+    
+    INFO("(%d,%d) - (%d,%d) %s", x,y,w,h,Name_BMP);
+    if (x >= 0 && x < width()
+    && y >= 0 && y < height()
+    && w > 0 && x + w <= width()
+    && h > 0 && y + h <= height()) {
+
+        BMP_Header.bfType = BF_TYPE;
+        BMP_Header.bfSize = (w * h * sizeof(RGBQUAD)) + sizeof(BMP_Header) + sizeof(BMP_Header);
+        BMP_Header.bfReserved1 = 0;
+        BMP_Header.bfReserved2 = 0;
+        BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Header);
+        
+        BMP_Info.biSize = sizeof(BMP_Info);
+        BMP_Info.biWidth = w;
+        BMP_Info.biHeight = h;
+        BMP_Info.biPlanes = 1;
+        BMP_Info.biBitCount = 24;
+        BMP_Info.biCompression = BI_RGB;
+        BMP_Info.biSizeImage = 0;
+        BMP_Info.biXPelsPerMeter = 0;
+        BMP_Info.biYPelsPerMeter = 0;
+        BMP_Info.biClrUsed = 0;
+        BMP_Info.biClrImportant = 0;
+
+        INFO("Writing {%s}", Name_BMP);
+        FILE *Image = fopen(Name_BMP, "wb");
+        if (!Image) {
+            ERR("File not found");
+            return(file_not_found);
+        }
+
+        // Be optimistic - don't check for errors.
+        //HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header));
+        fwrite(&BMP_Header, sizeof(char), sizeof(BMP_Header), Image);
+        //INFO("fwrite returned %d", r);
+        
+        //HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info));
+        fwrite(&BMP_Info, sizeof(char), sizeof(BMP_Info), Image);
+        //INFO("fwrite returned %d", r);
+        
+        int lineBufSize = ((24 * w + 7)/8);
+        uint8_t * lineBuffer = (uint8_t *)malloc(lineBufSize);
+        if (lineBuffer == NULL) {
+            fclose(Image);
+            ERR("Not enough RAM for lineBuffer");
+            return(not_enough_ram);
+        }
+        color_t * pixelBuffer = (color_t *)malloc(w * sizeof(color_t));
+        if (pixelBuffer == NULL) {
+            fclose(Image);
+            free(lineBuffer);
+            ERR("Not enough RAM for pixelBuffer");
+            return(not_enough_ram);
+        }
+        
+        // Read the display from the last line toward the top
+        // so we can write the file in one pass.
+        for (int j = h - 1; j >= 0; j--) {
+            // Read one line of pixels to a local buffer
+            if (getPixelStream(pixelBuffer, w, x,y+j) != noerror) {
+                ERR("getPixelStream error, and no recovery handler...");
+            }
+            // Convert the local buffer to RGBQUAD format
+            int lb = 0;
+            for (int i=0; i<w; i++) {
+                color_t pixel = pixelBuffer[x+i];
+                // Scale to 24-bits
+                RGBQUAD q = RGB16ToRGBQuad(pixel);
+                lineBuffer[lb++] = q.rgbBlue;
+                lineBuffer[lb++] = q.rgbGreen;
+                lineBuffer[lb++] = q.rgbRed;
+            }
+            // Write to disk
+            //HexDump("Line", lineBuffer, lineBufSize);
+            fwrite(lineBuffer, sizeof(char), lb, Image);
+        }
+        fclose(Image);       
+        INFO("Image closed"); 
+        return noerror;
+    } else {
+        return bad_parameter;
+    }
+}
+
 
 RetCode_t GraphicsDisplay::RenderBitmapFile(loc_t x, loc_t y, const char *Name_BMP)
 {
@@ -395,6 +484,13 @@
         fclose(Image);
         return(not_enough_ram);
     }
+    color_t * pixelBuffer = (color_t *)malloc(PixelWidth * sizeof(color_t));
+    if (pixelBuffer == NULL) {
+        free(colorPalette);
+        free(lineBuffer);
+        fclose(Image);
+        return(not_enough_ram);
+    }
 
     // the Raw Data records are padded to a multiple of 4 bytes
     int recordSize = 2;
@@ -431,17 +527,22 @@
                 if ((i & 1) == 0)
                     dPix >>= 4;
                 dPix &= 0x0F;
-                putp(RGBQuadToRGB16(colorPalette, dPix));
+                pixelBuffer[i] = RGBQuadToRGB16(colorPalette, dPix);
+                //putp(RGBQuadToRGB16(colorPalette, dPix));
             } else if (BPP_t == 8) {
-                putp(RGBQuadToRGB16(colorPalette, lineBuffer[i]));
+                pixelBuffer[i] = RGBQuadToRGB16(colorPalette, lineBuffer[i]);
+                //putp(RGBQuadToRGB16(colorPalette, lineBuffer[i]));
             } else if (BPP_t == 16) {
-                putp(lineBuffer[i]);
+                pixelBuffer[i] = lineBuffer[i];
+                //putp(lineBuffer[i]);
             } else if (BPP_t == 24) {
                 color_t color;
                 color = RGB(lineBuffer[i*3+2], lineBuffer[i*3+1], lineBuffer[i*3+0]);
-                putp(color);
+                pixelBuffer[i] = color;
+                //putp(color);
             }
         }
+        pixelStream(pixelBuffer, PixelWidth, x, y++);
     }
     free(lineBuffer);
     free(colorPalette);