⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 framebuffer.c

📁 ARM&linux 嵌入式系统 开发程序样例
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	// Directly access memory instead of call putpixel function 
	// to make more effective performance of drawing a line
	startOffset = y * LINE_SIZE + x1 * PIXEL_SIZE;

#ifdef DEBUG
		printf("DEBUG_INFO: x1 = %d, x2 = %d, y = %d, startOffset = 0x%x\n", x1, x2, y, startOffset);
#endif

	currPoint = frame_base + startOffset;
	for (x = x1; x <= x2; x++)
	{
		switch (BPP)
		{
			case 8:
				*(ByteType *)currPoint = _COLOR24_16(color) & 0xff;
				break;

			case 16:
				*(WordType *)currPoint = _COLOR24_16(color) & 0xffff;
				break;
		}
		currPoint += PIXEL_SIZE;
	}

	return;
}

// Draw a vertical line on the screen
void fb_DrawLine_V(int x, int y1, int y2, ColorType color/*, int xorm */)
{
	short currLine;
	void * currPoint;

	y1 = (y1 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y1;
	y2 = (y2 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y2;
	y1 = (y1 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y1;
	y2 = (y2 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y2;

	if (x < fb_clip.clipmin_x || x > fb_clip.clipmax_x)
	{
#ifdef ERR_DEBUG
		printf("DEBUG_INFO: Pixel out of screen range.\n");
		printf("DEBUG_INFO: x = %d, y1 = %d, y2 = %d\n", x, y1, y2);
#endif

		return;
	}

	if (y1 > y2)
	{
		short tmp;

		tmp = y1;
		y1 = y2;
		y2 = tmp;
	}

	// Directly access memory instead of call putpixel function 
	// to make more effective performance of drawing a line
	currPoint = (ByteType *)frame_base + y1 * LINE_SIZE + x * PIXEL_SIZE;

#ifdef DEBUG
		printf("DEBUG_INFO: x = %d, y1 = %d, y2 = %d, currPoint = 0x%x\n", x, y1, y2, currPoint);
#endif

	for (currLine = y1; currLine <= y2; currLine++) 
	{
		switch (BPP)
		{
			case 8:
				*((ByteType *)currPoint) = (_COLOR24_8(color) & 0xff);
				break;

			case 16:
				*((WordType *)currPoint) = (_COLOR24_16(color) & 0xffff);
				break;
		}

		// Make a LINE_SIZE increment to the currPoint,
		// in order to move point to the start position of next line
		(ByteType *)currPoint += LINE_SIZE;
	}	

  	return;
}

// Draw a rectangle frame on the screen
void fb_DrawRect(int x1, int y1, int x2, int y2, ColorType color)
{
	if (x1 > x2)
	{
		short tmp;

		tmp = x1;
		x1 = x2;
		x2 = tmp;
	}

	if (y1 > y2)
	{
		short tmp;

		tmp = y1;
		y1 = y2;
		y2 = tmp;
	}

	// Draw horitontal frame
	fb_DrawLine_H(x1, x2, y1, color);
	fb_DrawLine_H(x1, x2, y2, color);
	// Draw vertical frame
	fb_DrawLine_V(x1, y1 + 1, y2 - 1, color);
	fb_DrawLine_V(x2, y1 + 1, y2 - 1, color);

	return;
}
                                                                                                                                                                                                                                                                                                                                                            
// Draw a rectangle frame on the screen
void fb_FillRect(int x1, int y1, int x2, int y2, ColorType color)
{
	short currLine;
	unsigned long startOffset;
	void * currPoint;
	int x;

	if (x1 < fb_clip.clipmin_x || x1 > fb_clip.clipmax_x || 
		x2 < fb_clip.clipmin_x || x2 > fb_clip.clipmax_x ||
		y1 < fb_clip.clipmin_y || y1 > fb_clip.clipmax_y ||
		y2 < fb_clip.clipmin_y || y2 > fb_clip.clipmax_y)
	{
#ifdef ERR_DEBUG
		printf("DEBUG_INFO: Pixel out of screen range.\n");
		printf("DEBUG_INFO: x1 = %d, y1 = %d, x2 = %d, y2 = %d\n", x1, y1, x2, y2);
#endif

		x1 = (x1 < fb_clip.clipmin_x) ? fb_clip.clipmin_x : x1;
		x2 = (x2 < fb_clip.clipmin_x) ? fb_clip.clipmin_x : x2;
		y1 = (y1 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y1;
		y2 = (y2 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y2;

		x1 = (x1 > fb_clip.clipmax_x) ? fb_clip.clipmax_x : x1;
		x2 = (x2 > fb_clip.clipmax_x) ? fb_clip.clipmax_x : x2;
		y1 = (y1 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y1;
		y2 = (y2 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y2;
	}

	if (x1 > x2)
	{
		short tmp;

		tmp = x1;
		x1 = x2;
		x2 = tmp;
	}

	if (y1 > y2)
	{
		short tmp;

		tmp = y1;
		y1 = y2;
		y2 = tmp;
	}

	startOffset = y1 * LINE_SIZE + x1 * PIXEL_SIZE;

#ifdef DEBUG
	printf("DEBUG_INFO: x1 = %d, y1 = %d, x2 = %d, y2= %d, color = 0x%x\n", x1, y1, x2, y2, color);
#endif

	// Directly access memory instead of call putpixel function 
	// to make more effective performance of drawing a line
	for (currLine = y1; currLine <= y2; currLine++)
	{
		currPoint = frame_base + startOffset;
		for (x = x1; x <= x2; x++)
		{
			switch (BPP)
			{
				case 8:
					*(ByteType *)currPoint = _COLOR24_16(color) & 0xff;
					break;

				case 16:
					*(WordType *)currPoint = _COLOR24_16(color) & 0xffff;
					break;
			}
			(ByteType *)currPoint += PIXEL_SIZE;
		}
		// Make a LINE_SIZE increment to the startOffset,
		// in order to move point to the start position of next line
		startOffset += SCREEN_WIDTH * PIXEL_SIZE;
	}

	return;
}

// Save screen content of specified range
void fb_SaveRange(int x1, int y1, int x2, int y2, ByteType * buffer, int * sw, int * sh)
{
	short currLine;
	unsigned long startOffset;
	void * currPoint;
	void * pBuf;
	int x;

	if (x1 < fb_clip.clipmin_x || x1 > fb_clip.clipmax_x || 
		x2 < fb_clip.clipmin_x || x2 > fb_clip.clipmax_x ||
		y1 < fb_clip.clipmin_y || y1 > fb_clip.clipmax_y ||
		y2 < fb_clip.clipmin_y || y2 > fb_clip.clipmax_y)
	{
#ifdef ERR_DEBUG
		printf("DEBUG_INFO: Pixel out of screen range.\n");
		printf("DEBUG_INFO: x1 = %d, y1 = %d, x2 = %d, y2 = %d\n", x1, y1, x2, y2);
#endif

		x1 = (x1 < fb_clip.clipmin_x) ? fb_clip.clipmin_x : x1;
		x2 = (x2 < fb_clip.clipmin_x) ? fb_clip.clipmin_x : x2;
		y1 = (y1 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y1;
		y2 = (y2 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y2;

		x1 = (x1 > fb_clip.clipmax_x) ? fb_clip.clipmax_x : x1;
		x2 = (x2 > fb_clip.clipmax_x) ? fb_clip.clipmax_x : x2;
		y1 = (y1 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y1;
		y2 = (y2 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y2;
	}

	if (x1 > x2)
	{
		short tmp;

		tmp = x1;
		x1 = x2;
		x2 = tmp;
	}

	if (y1 > y2)
	{
		short tmp;

		tmp = y1;
		y1 = y2;
		y2 = tmp;
	}

	startOffset = y1 * LINE_SIZE + x1 * PIXEL_SIZE;

	if (buffer == NULL)
	{
		printf("buffer is NULL.\n");
		return;
	}

#ifdef DEBUG
	printf("DEBUG_INFO: x1 = %d, y1 = %d, x2 = %d, y2= %d\n", x1, y1, x2, y2);
#endif

	// Directly access memory instead of call putpixel function 
	// to make more effective performance of drawing a line
	pBuf = buffer;
//	printf("buffer = 0x%8x\n", buffer);
//	printf("DEBUG_INFO: x1 = %d, y1 = %d, x2 = %d, y2= %d\n", x1, y1, x2, y2);
	for (currLine = y1; currLine <= y2; currLine++)
	{
//		printf("currLine = %d\n", currLine);
		currPoint = frame_base + startOffset;
//		printf("pBuf = 0x%8x, currPoint = 0x%8x\n", pBuf, currPoint);
		for (x = x1; x <= x2; x++)
		{
			switch (BPP)
			{
				case 8:
					*(ByteType *)pBuf = *(ByteType *)currPoint;
					break;

				case 16:
					*(WordType *)pBuf = *(WordType *)currPoint;
					break;
			}
			(ByteType *)currPoint += PIXEL_SIZE;
			(ByteType *)pBuf += PIXEL_SIZE;
		}
		// Make a LINE_SIZE increment to the startOffset,
		// in order to move point to the start position of next line
		startOffset += SCREEN_WIDTH * PIXEL_SIZE;
	}

	if (sw != NULL)
		*sw = x2 - x1 + 1;
	if (sh != NULL)
		*sh = y2 - y1 + 1;

	return;
}

// Load saved screen content to specified range
void fb_LoadRange(int x1, int y1, int x2, int y2, ByteType * buffer, int sw, int sh)
{
	short currLine;
	unsigned long startOffset;
	void * linePointer;
	void * currPoint;
	void * pBuf;
	int x;
	int max_x, max_y;

	if (x1 < fb_clip.clipmin_x || x1 > fb_clip.clipmax_x || 
		x2 < fb_clip.clipmin_x || x2 > fb_clip.clipmax_x ||
		y1 < fb_clip.clipmin_y || y1 > fb_clip.clipmax_y ||
		y2 < fb_clip.clipmin_y || y2 > fb_clip.clipmax_y)
	{
#ifdef ERR_DEBUG
		printf("DEBUG_INFO: Pixel out of screen range.\n");
		printf("DEBUG_INFO: x1 = %d, y1 = %d, x2 = %d, y2 = %d\n", x1, y1, x2, y2);
#endif

		x1 = (x1 < fb_clip.clipmin_x) ? fb_clip.clipmin_x : x1;
		x2 = (x2 < fb_clip.clipmin_x) ? fb_clip.clipmin_x : x2;
		y1 = (y1 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y1;
		y2 = (y2 < fb_clip.clipmin_y) ? fb_clip.clipmin_y : y2;

		x1 = (x1 > fb_clip.clipmax_x) ? fb_clip.clipmax_x : x1;
		x2 = (x2 > fb_clip.clipmax_x) ? fb_clip.clipmax_x : x2;
		y1 = (y1 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y1;
		y2 = (y2 > fb_clip.clipmax_y) ? fb_clip.clipmax_y : y2;
	}

	if (x1 > x2)
	{
		short tmp;

		tmp = x1;
		x1 = x2;
		x2 = tmp;
	}

	if (y1 > y2)
	{
		short tmp;

		tmp = y1;
		y1 = y2;
		y2 = tmp;
	}

	startOffset = y1 * LINE_SIZE + x1 * PIXEL_SIZE;

	if (buffer == NULL)
	{
		printf("buffer is NULL.\n");
		return;
	}

#ifdef DEBUG
	printf("DEBUG_INFO: x1 = %d, y1 = %d, x2 = %d, y2= %d\n", x1, y1, x2, y2);
#endif

	max_x = x2 > (x1 + sw - 1) ? (x1 + sw - 1) : x2;
	max_y = y2 > (y1 + sh - 1) ? (y1 + sh - 1) : y2;

	// Directly access memory instead of call putpixel function 
	// to make more effective performance of drawing a line
	linePointer = buffer;
	pBuf = buffer;
//	printf("buffer = 0x%8x\n", buffer);
//	printf("max_x = %d, max_y = %d\n", max_x, max_y);
	for (currLine = y1; currLine <= max_y; currLine++)
	{
		currPoint = frame_base + startOffset;
		pBuf = linePointer;
		for (x = x1; x <= max_x; x++)
		{
			switch (BPP)
			{
				case 8:
					 *(ByteType *)currPoint = *(ByteType *)pBuf;
					break;

				case 16:
					*(WordType *)currPoint = *(WordType *)pBuf;
					break;
			}
			(ByteType *)currPoint += PIXEL_SIZE;
			(ByteType *)pBuf += PIXEL_SIZE;
		}
		// Make a LINE_SIZE increment to the startOffset,
		// in order to move point to the start position of next line
		startOffset += SCREEN_WIDTH * PIXEL_SIZE;
		(ByteType *)linePointer += sw * PIXEL_SIZE;
	}

	return;
}

// GAL Interface functions
int InitFB(GFX * gfx)
{
	if (strcmp(gfx->gfx_id, "FrameBuffer") != 0)
		return -1;

	fb_Init();
    
	gfx->gfx_width = fb_GetScreenWidth();
	gfx->gfx_height = fb_GetScreenHeight();
	gfx->gfx_bpp = fb_GetScreenBpp();
	gfx->gfx_colors = fb_GetScreenColors();
	gfx->gfx_clip = &fb_clip;

	gfx->putpixel	= fb_PutPixel;
	gfx->getpixel = fb_GetPixel;

	gfx->drawvline = fb_DrawLine_V;
	gfx->drawhline = fb_DrawLine_H;

	gfx->drawrect = fb_DrawRect;
	gfx->fillrect = fb_FillRect;

	gfx->drawellipse = NULL;
	gfx->fillellipse = NULL;
	gfx->drawcircle = NULL;
	gfx->fillcircle = NULL;

	gfx->putchar = NULL;
	gfx->putstr = NULL;

	gfx->clearscreen = fb_Clear;

	gfx->saverange = fb_SaveRange;
	gfx->loadrange = fb_LoadRange;

	return 0;
}

void ReleaseFB(GFX * gfx)
{
	fb_Release();
}

#endif	// __GAL_DRIVER_FB_C

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -