📄 offscr1bpp.c
字号:
//*****************************************************************************
//
// offscr1bpp.c - 1 BPP off-screen display buffer driver.
//
// Copyright (c) 2008-2009 Luminary Micro, Inc. All rights reserved.
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws. All rights are reserved. You may not combine
// this software with "viral" open-source software in order to form a larger
// program. Any use in violation of the foregoing restrictions may subject
// the user to criminal sanctions under applicable laws, as well as to civil
// liability for the breach of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 5228 of the Stellaris Graphics Library.
//
//*****************************************************************************
#include "driverlib/debug.h"
#include "grlib/grlib.h"
//*****************************************************************************
//
//! \addtogroup primitives_api
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Translates a 24-bit RGB color to a display driver-specific color.
//
// \param c is the 24-bit RGB color. The least-significant byte is the blue
// channel, the next byte is the green channel, and the third byte is the red
// channel.
//
// This macro translates a 24-bit RGB color into a value that can be written
// into the display's frame buffer in order to reproduce that color, or the
// closest possible approximation of that color.
//
// \return Returns the display-driver specific color.
//
//*****************************************************************************
#define DPYCOLORTRANSLATE(c) ((((((c) & 0x00ff0000) >> 16) * 19661) + \
((((c) & 0x0000ff00) >> 8) * 38666) + \
(((c) & 0x000000ff) * 7209)) / \
(65536 * 128))
//*****************************************************************************
//
//! Draws a pixel on the screen.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the pixel.
//! \param lY is the Y coordinate of the pixel.
//! \param ulValue is the color of the pixel.
//!
//! This function sets the given pixel to a particular color. The coordinates
//! of the pixel are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
GrOffScreen1BPPPixelDraw(void *pvDisplayData, long lX, long lY,
unsigned long ulValue)
{
unsigned char *pucData;
long lBytesPerRow;
//
// Check the arguments.
//
ASSERT(pvDisplayData);
//
// Create a character pointer for the display-specific data (which points
// to the image buffer).
//
pucData = (unsigned char *)pvDisplayData;
//
// Compute the number of bytes per row in the image buffer.
//
lBytesPerRow = (*(unsigned short *)(pucData + 1) + 7) / 8;
//
// Get the offset to the byte of the image buffer that contains the pixel
// in question.
//
pucData += (lBytesPerRow * lY) + (lX / 8) + 5;
//
// Determine how much to shift to get to the bit that contains this pixel.
//
lX = 7 - (lX & 7);
//
// Write this pixel into the image buffer.
//
*pucData = (*pucData & ~(1 << lX)) | (ulValue << lX);
}
//*****************************************************************************
//
//! Draws a horizontal sequence of pixels on the screen.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the first pixel.
//! \param lY is the Y coordinate of the first pixel.
//! \param lX0 is sub-pixel offset within the pixel data, which is valid for 1
//! or 4 bit per pixel formats.
//! \param lCount is the number of pixels to draw.
//! \param lBPP is the number of bits per pixel; must be 1, 4, or 8.
//! \param pucData is a pointer to the pixel data. For 1 and 4 bit per pixel
//! formats, the most significant bit(s) represent the left-most pixel.
//! \param pucPalette is a pointer to the palette used to draw the pixels.
//!
//! This function draws a horizontal sequence of pixels on the screen, using
//! the supplied palette. For 1 bit per pixel format, the palette contains
//! pre-translated colors; for 4 and 8 bit per pixel formats, the palette
//! contains 24-bit RGB values that must be translated before being written to
//! the display.
//!
//! \return None.
//
//*****************************************************************************
static void
GrOffScreen1BPPPixelDrawMultiple(void *pvDisplayData, long lX, long lY,
long lX0, long lCount, long lBPP,
const unsigned char *pucData,
const unsigned char *pucPalette)
{
unsigned char *pucPtr;
unsigned long ulByte;
long lBytesPerRow;
//
// Check the arguments.
//
ASSERT(pvDisplayData);
ASSERT(pucData);
ASSERT(pucPalette);
//
// Create a character pointer for the display-specific data (which points
// to the image buffer).
//
pucPtr = (unsigned char *)pvDisplayData;
//
// Compute the number of bytes per row in the image buffer.
//
lBytesPerRow = (*(unsigned short *)(pucPtr + 1) + 7) / 8;
//
// Get the offset to the byte of the image buffer that contains the
// starting pixel.
//
pucPtr += (lBytesPerRow * lY) + (lX / 8) + 5;
//
// Determine the bit position of the starting pixel.
//
lX = 7 - (lX & 7);
//
// Determine how to interpret the pixel data based on the number of bits
// per pixel.
//
switch(lBPP)
{
//
// The pixel data is in 1 bit per pixel format.
//
case 1:
{
//
// Loop while there are more pixels to draw.
//
while(lCount)
{
//
// Get the next byte of image data.
//
ulByte = *pucData++;
//
// Loop through the pixels in this byte of image data.
//
for(; (lX0 < 8) && lCount; lX0++, lCount--)
{
//
// Draw this pixel in the appropriate color.
//
*pucPtr = ((*pucPtr & ~(1 << lX)) |
((((unsigned long *)pucPalette)[(ulByte >>
(7 - lX0)) &
1]) << lX));
if(lX-- == 0)
{
lX = 7;
pucPtr++;
}
}
//
// Start at the beginning of the next byte of image data.
//
lX0 = 0;
}
//
// The image data has been drawn.
//
break;
}
//
// The pixel data is in 4 bit per pixel format.
//
case 4:
{
//
// Loop while there are more pixels to draw. "Duff's device" is
// used to jump into the middle of the loop if the first nibble of
// the pixel data should not be used. Duff's device makes use of
// the fact that a case statement is legal anywhere within a
// sub-block of a switch statement. See
// http://en.wikipedia.org/wiki/Duff's_device for detailed
// information about Duff's device.
//
switch(lX0 & 1)
{
case 0:
while(lCount)
{
//
// Get the upper nibble of the next byte of pixel data
// and extract the corresponding entry from the
// palette.
//
ulByte = (*pucData >> 4) * 3;
ulByte = (*(unsigned long *)(pucPalette + ulByte) &
0x00ffffff);
//
// Translate this palette entry and write it to the
// screen.
//
*pucPtr = ((*pucPtr & ~(1 << lX)) |
(DPYCOLORTRANSLATE(ulByte) << lX));
if(lX-- == 0)
{
lX = 7;
pucPtr++;
}
//
// Decrement the count of pixels to draw.
//
lCount--;
//
// See if there is another pixel to draw.
//
if(lCount)
{
case 1:
//
// Get the lower nibble of the next byte of pixel
// data and extract the corresponding entry from
// the palette.
//
ulByte = (*pucData++ & 15) * 3;
ulByte = (*(unsigned long *)(pucPalette + ulByte) &
0x00ffffff);
//
// Translate this palette entry and write it to the
// screen.
//
*pucPtr = ((*pucPtr & ~(1 << lX)) |
(DPYCOLORTRANSLATE(ulByte) << lX));
if(lX-- == 0)
{
lX = 7;
pucPtr++;
}
//
// Decrement the count of pixels to draw.
//
lCount--;
}
}
}
//
// The image data has been drawn.
//
break;
}
//
// The pixel data is in 8 bit per pixel format.
//
case 8:
{
//
// Loop while there are more pixels to draw.
//
while(lCount--)
{
//
// Get the next byte of pixel data and extract the
// corresponding entry from the palette.
//
ulByte = *pucData++ * 3;
ulByte = *(unsigned long *)(pucPalette + ulByte) & 0x00ffffff;
//
// Translate this palette entry and write it to the screen.
//
*pucPtr = ((*pucPtr & ~(1 << lX)) |
(DPYCOLORTRANSLATE(ulByte) << lX));
if(lX-- == 0)
{
lX = 7;
pucPtr++;
}
}
//
// The image data has been drawn.
//
break;
}
}
}
//*****************************************************************************
//
//! Draws a horizontal line.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX1 is the X coordinate of the start of the line.
//! \param lX2 is the X coordinate of the end of the line.
//! \param lY is the Y coordinate of the line.
//! \param ulValue is the color of the line.
//!
//! This function draws a horizontal line on the display. The coordinates of
//! the line are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
GrOffScreen1BPPLineDrawH(void *pvDisplayData, long lX1, long lX2, long lY,
unsigned long ulValue)
{
long lBytesPerRow, lMask;
unsigned char *pucData;
//
// Check the arguments.
//
ASSERT(pvDisplayData);
//
// Create a character pointer for the display-specific data (which points
// to the image buffer).
//
pucData = (unsigned char *)pvDisplayData;
//
// Compute the number of bytes per row in the image buffer.
//
lBytesPerRow = (*(unsigned short *)(pucData + 1) + 7) / 8;
//
// Get the offset to the byte of the image buffer that contains the
// starting pixel.
//
pucData += (lBytesPerRow * lY) + (lX1 / 8) + 5;
//
// Copy the pixel value into all 32 pixels of the unsigned long. This will
// be used later to write multiple pixels into memory (as opposed to one at
// a time).
//
if(ulValue)
{
ulValue = 0xffffffff;
}
//
// See if the current buffer byte contains pixels that should be left
// unmodified.
//
if(lX1 & 7)
{
//
// Compute the mask to access only the appropriate pixels within this
// byte. The line may start and stop within this byte, so the mask may
// need to be shortened to account for this situation.
//
lMask = 8 - (lX1 & 7);
if(lMask > (lX2 - lX1 + 1))
{
lMask = lX2 - lX1 + 1;
}
lMask = ((1 << lMask) - 1) << (8 - (lX1 & 7) - lMask);
//
// Draw the appropriate pixels within this byte.
//
*pucData = (*pucData & ~lMask) | (ulValue & lMask);
pucData++;
lX1 = (lX1 + 7) & ~7;
}
//
// See if the buffer pointer is not half-word aligned and there are at
// least eight pixels left to draw.
//
if(((unsigned long)pucData & 1) && ((lX2 - lX1) > 6))
{
//
// Draw eight pixels to half-word align the buffer pointer.
//
*pucData++ = ulValue & 0xff;
lX1 += 8;
}
//
// See if the buffer pointer is not word aligned and there are at least
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -