/*********************************************************************** * * Function: swim_window_scroll * * Purpose: Scrolls the window up one line * * Processing: * From the vertical font size and lower window limit, determine the * move indices for the move operation. Move all lines up by the * numbers of pixel in the present font height until the top of the * window has been reached. * * Parameters: * win : Window identifier * lines : Number of lines to scroll up * * Outputs: None * * Returns: Nothing * * Notes: This function is private to this module. * **********************************************************************/ void swim_window_scroll(SWIM_WINDOW_T *win, INT_32 lines) { INT_32 yref1 = win->ypvmin; INT_32 yref2 = yref1 + lines; while (yref2 <= win->ypvmax) { /* Move a single line at a time */ swim_driver_copy_raster(win, win->xpvmin, yref2, win->xpvmin, yref1, win->xpvmax - win->xpvmin + 1); /* Next lines */ yref1++; yref2++; } /* Clear out bottom lines */ yref1 = win->yvpos; while (yref1 <= win->ypvmax) { /* Clear a single line at a time */ swim_driver_fill_raster(win, win->xpvmin, yref1, win->bkg, win->xpvmax - win->xpvmin + 1); yref1++; } }
/*********************************************************************** * * Function: swim_clear_screen * * Purpose: * Fills the draw area of the display with the selected color * * Processing: * Loop through all virtual window (draw area) locations and * updates them with the passed color value. * * Parameters: * win : Window identifier * colr : Color to place in the window * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ void swim_clear_screen(SWIM_WINDOW_T *win, COLOR_T color) { INT_32 y; for (y = win->ypvmin; y <= win->ypvmax; y++) { swim_driver_fill_raster(win, win->xpvmin, y, color, 1 + win->xpvmax - win->xpvmin); } }
/*********************************************************************** * * Function: swim_put_box * * Purpose: Place a box with corners (X1, Y1) and (X2, Y2) * * Processing: * See function. * * Parameters: * win : Window identifier * x1 : Virtual left position of box * y1 : Virtual upper position of box * x2 : Virtual right position of box * y2 : Virtual lower position of box * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ void swim_put_box( SWIM_WINDOW_T *win, INT_32 x1, INT_32 y1, INT_32 x2, INT_32 y2) { INT_32 xinc, yinc; if (x1 > x2) { xinc = x1; x1 = x2; x2 = xinc; } /* Swap y1 and y2 if y1 is larger than y2 */ if (y1 > y2) { yinc = y1; y1 = y2; y2 = yinc; } /* Convert virtual coordinates to physical coordinates */ x1 = x1 + win->xpvmin; x2 = x2 + win->xpvmin; y1 = y1 + win->ypvmin; y2 = y2 + win->ypvmin; /* Clip boxes to window sizes */ if (x1 < win->xpvmin) { x1 = win->xpvmin; } if (y1 < win->ypvmin) { y1 = win->ypvmin; } if (x2 > win->xpvmax) { x2 = win->xpvmax; } if (y2 > win->ypvmax) { y2 = win->ypvmax; } /* Get X and Y differences */ xinc = x2 - x1; yinc = y2 - y1; /* Make outer edge of box in pen color */ swim_put_line_raw(win, x1, y1, x2, y1); swim_put_line_raw(win, x2, y1, x2, y2); swim_put_line_raw(win, x2, y2, x1, y2); swim_put_line_raw(win, x1, y2, x1, y1); /* Increment X, Y values so they won't overwrite the edge */ x1++; y1++; /* Draw inside if NOT transparent */ if ((!win->tfill) && (x1 < x2)) { /* Draw the box inside with the fill color */ while (y1 < y2) { swim_driver_fill_raster(win, x1, y1, win->fill, x2 - x1); y1++; } } }
/*********************************************************************** * * Function: swim_put_triangle * * Purpose: * Purpose: Draw a triangle in the virtual window * * Processing: * See function. * * Parameters: * win : Window identifier * x : Virtual X position of the diamond * y : Virtual Y position of the diamond * rx : Radius for horizontal * ry : Radius for vertical * orientation : Orientation: up, right, down or left * * Outputs: None * * Returns: Nothing * * Notes: * This function supports clipping. * **********************************************************************/ void swim_put_triangle( SWIM_WINDOW_T *win, INT_32 ix, INT_32 iy, INT_32 irx, INT_32 iry, T_triangle_orientation orientation) { INT_32 xinc, idy, xleft, xright, ytop, ybot, pixel, ydsp, x, y, rx, ry; x = ix; y = iy; switch (orientation) { case up: rx = irx; ry = (iry << 1); xleft = x - rx; xright = x + rx; ytop = y - ry; ybot = y; break; case right: rx = (irx << 1); ry = iry; xleft = x; xright = x + rx; ytop = y - ry; ybot = y + ry; break; case down: rx = irx; ry = (iry << 1); xleft = x - rx; xright = x + rx; ytop = y; ybot = y + ry; break; case left: rx = (irx << 1); ry = iry; xleft = x - rx; xright = x; ytop = y - ry; ybot = y + ry; break; default: return; } /* For center line, limit to size of the window */ if (xleft < win->xpvmin) { xleft = win->xpvmin; } if (xright > win->xpvmax) { xright = win->xpvmax; } /* Draw the center lines in the pen color */ switch (orientation) { case up: if ((y >= win->ypvmin) && (y <= win->ypvmax)) { swim_driver_fill_raster(win, xleft, y, win->pen, 1 + xright - xleft); } break; case right: if ((x >= win->xpvmin) && (x <= win->xpvmax)) { /* Draw the left and right pixels of the center line in the pen color */ swim_driver_put_pixel(win, xleft, y, win->pen); swim_driver_put_pixel(win, xright, y, win->pen); /* Draw the center line first in the fill color */ if ((y >= win->ypvmin) && (y <= win->ypvmax)) { swim_driver_fill_raster(win, xleft+1, y + win->ypmin, win->fill, xright - xleft - 1); } /* Draw the vertical line */ for (pixel = (ytop); pixel < (ybot); pixel++) { swim_driver_put_pixel(win, x, pixel + win->ypmin, win->pen); } } break; case down: if ((y >= win->ypvmin) && (y <= win->ypvmax)) { swim_driver_fill_raster(win, xleft, y + win->ypmin, win->pen, 1 + xright - xleft); } break; case left: if ((x >= win->xpvmin) && (x <= win->xpvmax)) { /* Draw the left and right pixels of the center line in the pen color */ swim_driver_put_pixel(win, xleft, y, win->pen); swim_driver_put_pixel(win, xright, y, win->pen); /* Draw the center line first in the fill color */ if ((y >= win->ypvmin) && (y <= win->ypvmax)) { swim_driver_fill_raster(win, xleft + 1, y + win->ypmin, win->fill, xright - xleft - 1); } /* Draw the vertical line */ for (pixel = (ytop); pixel < (ybot); pixel++) { swim_driver_put_pixel(win, x, pixel + win->ypmin, win->pen); } } break; default: break; } /* Draw the triangle */ for (idy = 1; idy <= ry; idy++) { /* Compute left and right endpoints for the horizontal line */ xinc = ((ry - idy) * rx); switch (orientation) { case up: xleft = x - xinc / ry; xright = x + xinc / ry; break; case right: xleft = x; xright = x + xinc / ry; break; case down: xleft = x - xinc / ry; xright = x + xinc / ry; break; case left: xleft = x - xinc / ry; xright = x; break; default: break; } /* Clip left and right edges if needed */ if (xleft < win->xpvmin) { xleft = win->xpvmin; } if (xright > win->xpvmax) { xright = win->xpvmax; } /* Convert virtual coordinates to physical coordinates */ xleft = xleft + win->xpmin; xright = xright + win->xpmin; /* Only render top line if it is visible */ if ((orientation != down) && ((y - idy) >= win->ypvmin)) //if ( (orientation == up) && ((y - idy) >= win->ypvmin) ) { /* Convert to physical coordinate */ ydsp = ((y - idy) + win->ypmin); /* Draw the left pixel of the line in the pen color */ swim_driver_put_pixel(win, xleft, ydsp, win->pen); /* Draw top line in fill color */ swim_driver_fill_raster(win, xleft + 1, ydsp, xright - xleft - 1, win->fill); /* Draw the right pixel of the line in the pen color */ swim_driver_put_pixel(win, xright, ydsp, win->pen); } /* Only render bottom line if it is visible */ if ((orientation != up) && ((y + idy) <= win->ypvmax)) //if ( (orientation == down) && ((y + idy) <= win->ypvmax) ) { /* Convert to physical offset */ ydsp = ((y + idy) + win->ypmin) * win->xpsize; /* Draw the left pixel of the line in the pen color */ swim_driver_put_pixel(win, xleft, ydsp, win->pen); /* Draw top line in fill color */ swim_driver_fill_raster(win, xleft + 1, ydsp, xright - xleft - 1, win->fill); /* Draw the right pixel of the line in the pen color */ swim_driver_put_pixel(win, xright, ydsp, win->pen); } } }
/*********************************************************************** * * Function: swim_put_diamond * * Purpose: * Purpose: Draw a diamond in the virtual window * * Processing: * See function. * * Parameters: * win : Window identifier * x : Virtual X position of the diamond * y : Virtual Y position of the diamond * rx : Radius for horizontal * ry : Radius for vertical * * Outputs: None * * Returns: Nothing * * Notes: * This function supports clipping. * **********************************************************************/ void swim_put_diamond( SWIM_WINDOW_T *win, INT_32 x, INT_32 y, INT_32 rx, INT_32 ry) { INT_32 xinc, idy, xleft, xright, pixel, ydsp; /* For center line, limit to size of the window */ xleft = x - rx; if (xleft < win->xpvmin) { xleft = win->xpvmin; } xright = x + rx; if (xright > win->xpvmax) { xright = win->xpvmax; } /* Draw the left and right pixels of the center line in the pen color */ swim_driver_put_pixel(win, xleft, y + win->ypmin, win->pen); swim_driver_put_pixel(win, xright, y + win->ypmin, win->pen); /* Draw the center line first in the fill color */ if ((y >= win->ypvmin) && (y <= win->ypvmax)) { for (pixel = (xleft + 1); pixel <= (xright - 1); pixel++) { swim_driver_put_pixel(win, pixel, y + win->ypmin, win->fill); } } /* Draw the top and bottom halves of the diamond */ for (idy = 1; idy <= ry; idy++) { /* Compute left and right endpoints for the horizontal line */ xinc = ((ry - idy) * rx); xleft = x - xinc / ry; xright = x + xinc / ry; /* Clip left and right edges if needed */ if (xleft < win->xpvmin) { xleft = win->xpvmin; } if (xright > win->xpvmax) { xright = win->xpvmax; } /* Convert virtual coordinates to physical coordinates */ xleft = xleft + win->xpmin; xright = xright + win->xpmin; /* Only render top line if it is visible */ if ((y - idy) >= win->ypvmin) { /* Convert to physical coordinate */ ydsp = ((y - idy) + win->ypmin); /* Draw the left pixel of the line in the pen color */ swim_driver_put_pixel(win, xleft, ydsp, win->pen); /* Draw top line in fill color */ swim_driver_fill_raster(win, xleft + 1, ydsp, (xright - xleft - 1), win->fill); /* Draw the right pixel of the line in the pen color */ swim_driver_put_pixel(win, xright, ydsp, win->pen); } /* Only render bottom line if it is visible */ if ((y + idy) <= win->ypvmax) { /* Convert to physical offset */ ydsp = ((y + idy) + win->ypmin) * win->xpsize; /* Draw the left pixel of the line in the pen color */ swim_driver_put_pixel(win, xleft, ydsp, win->pen); /* Draw top line in fill color */ swim_driver_fill_raster(win, xleft + 1, ydsp, (xright - xleft - 1), win->fill); /* Draw the right pixel of the line in the pen color */ swim_driver_put_pixel(win, xright, ydsp, win->pen); } } }
/*---------------------------------------------------------------------------* * Routine: IHidePage0 *---------------------------------------------------------------------------* * Description: * Copy the current viewed page to the hidden page 1 and then show * page 1 (hiding page 0 as changes are about to be made). *---------------------------------------------------------------------------*/ int SUIDrawBitmap(const TUInt8 *aBitmapImage, TUInt32 aX, TUInt32 aY) { static T_pixelColor ColorPalette[256]; TUInt32 bitmapHeaderSize; TUInt32 imageOffset; TUInt32 height, width; TUInt16 compressionMethod; TUInt32 colorPaletteSize; TUInt16 numBPP; TUInt8 *p = (TUInt8 *)aBitmapImage; TUInt8 paddingCount; TUInt32 i, x, y; TUInt8 firstByte, numPixelsToDraw, colorIndex; bitmapHeaderSize = *((TVUInt32 *)(p + BMP_HEADER_SIZE)); imageOffset = *((TVUInt32 *)(p + FILE_IMAGE_OFFSET)); width = *((TVUInt32 *)(p + BMP_WIDTH)); height = *((TVUInt32 *)(p + BMP_HEIGHT)); /* NOTE: Technically, compressionMethod should be a 32-bit number and not a * 16-bit number, but on the LPC2478 and crossworks, the address being * retrieved for the logo is across a 32-bit boundary and is causing the * compiler to incorrectly see this as 0x00080001 instead of 0x000000001. * For now, we're going to just use 16-bit values since all compression * values are 0-7. -- lshields 3/26/2013 * Additionally, make them all volatile. The compiler is over optimizing * too. Weird. */ compressionMethod = *((TVUInt16 *)(p + BMP_COMPRESSION_METHOD)); colorPaletteSize = *((TVUInt32 *)(p + BMP_COLOR_PALETTE_SIZE)); numBPP = *((TVUInt32 *)(p + BMP_NUM_BPP)); if(colorPaletteSize > 256) { printf("Bitmap Error: Invalid Color Palette Size.\r\n"); return 0; } if(numBPP != 8) { printf("Bitmap Error: Bitmap must be a 256 color image.\r\n"); return 0; } // Determine the padding count - each line must end in 4 byte boundaries paddingCount = (4-(width & 3)) & 3; p = (TUInt8 *)(aBitmapImage) + FILE_HEADER_SIZE + bitmapHeaderSize; for(i=0; i<colorPaletteSize; i++) { ColorPalette[i] = ConvertColor32(*((TUInt32 *)p)); p += 4; } p = (TUInt8 *)(aBitmapImage) + imageOffset; if(compressionMethod == BI_RLE8) { for(y=height; y>0; y--) { x=0; while(x<width) { firstByte = *(p++); if(firstByte != 0) { // First byte is greater than 1. We just need to read the color index // and draw the number pixels equal to the first byte. colorIndex = *(p++); // Draw a raster of pixels swim_driver_fill_raster( &G_SUISettings.iWindow, x+aX, y+aY-1, ColorPalette[colorIndex], firstByte); x += firstByte; } else { // First byte is 0. The next byte will specify the number of pixels that // will follow. numPixelsToDraw = *(p++); swim_driver_put_raster_indexed_color(&G_SUISettings.iWindow, x+aX, y+aY-1, p, ColorPalette, numPixelsToDraw); x += numPixelsToDraw; p += numPixelsToDraw; if(numPixelsToDraw & 1) { // The next firstByte will always start on an even count. We must // advance one byte after this pixel sequence if numPixelsToDraw // is odd. p++; } } } // We advance p if there is padding at the end of the line p += paddingCount; } } else if(compressionMethod == BI_RGB) { for(y=height; y>0; y--) { swim_driver_put_raster_indexed_color(&G_SUISettings.iWindow, aX, y+aY-1, p, ColorPalette, width); p += width; p += paddingCount; } } else { printf("Bitmap Error: Invalid Compression Method.\r\n"); return 0; } return 1; }