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

📄 lcd_control.c

📁 嵌入式linux(arm9)的平台下
💻 C
字号:

#include "lcd_control.h"
#include "example.h"
#include "dib2device/au_bitmap.h"
#include "gpio.h"

#define MAX_STATUS		5
#define MENU_TOP		100

#ifdef HYDROGEN3

#define MAX_OS			2
#define BITMAP_COUNT	18
enum BITMAPS
{
	AMD,
	AMD_ARROW,
	BOARD_LOGO,
	TOP_ERROR,
	TOP_LOADING,
	TOP_SELECT_OS,
	MIDDLE_CANNOT_FIND_FILE,
	MIDDLE_OPEN_PDA_SELECT,
	MIDDLE_OPEN_PDA,
	MIDDLE_PLEASE_WAIT,
	MIDDLE_WINDOWS_CE_SELECT,
	MIDDLE_WINDOWS_CE,
	BOTTOM,
	STATUS_BAR
};
#endif

#ifdef PB1100
#define BITMAP_COUNT	13
enum BITMAPS
{
	AMD,
	AMD_ARROW,
	BOARD_LOGO,
	TOP_ERROR,
	TOP_LOADING,
	MIDDLE_CANNOT_FIND_FILE,
	MIDDLE_PLEASE_WAIT,
	BOTTOM,
	STATUS_BAR
};
#endif
	

Bitmap* bitmaps[BITMAP_COUNT];

int statusIndex = 0;
int statusDirection = 1;
int lcdReady = 1;

int menu_x = 0;
int menu_y = 0;
int menu_width = 0;
int menu_height = 0;

unsigned short* framebuffer;
unsigned short* au1100lcdInit();


#ifdef HYDROGEN3


#define JOYSTICK_UP			9
#define JOYSTICK_DOWN		11
#define JOYSTICK_SELECT		1

void lcdDisplayOSMenu()
{
	Bitmap* bmps[4];
	bmps[0] = bitmaps[TOP_SELECT_OS];
	bmps[1] = bitmaps[MIDDLE_WINDOWS_CE];
	bmps[2] = bitmaps[MIDDLE_OPEN_PDA];
	bmps[3] = bitmaps[BOTTOM];

	lcdDisplayMenu(bmps, 4);
}

void lcdDisplayLoadingMenu(int OS)
{
	Bitmap* bmps[4];
	bmps[0] = bitmaps[TOP_LOADING];
	switch(OS)
	{
		case WINDOWS: 
			bmps[1] = bitmaps[MIDDLE_WINDOWS_CE];
			break;
		case OPEN_PDA:
			bmps[1] = bitmaps[MIDDLE_OPEN_PDA];
			break;
	}
	bmps[2] = bitmaps[MIDDLE_PLEASE_WAIT];
	bmps[3] = bitmaps[BOTTOM];

	lcdDisplayMenu(bmps, 4);
}

void lcdDisplayErrorMenu()
{
	Bitmap* bmps[3];
	bmps[0] = bitmaps[TOP_ERROR];
	bmps[1] = bitmaps[MIDDLE_CANNOT_FIND_FILE];
	bmps[2] = bitmaps[BOTTOM];

	lcdDisplayMenu(bmps, 3);
	lcdGetButton();
}

int lcdGetJoystickButton()
{
	int down = 0;
	int up = 0;
	int select = 0;

	while(	(down = gpioRead(JOYSTICK_DOWN))		&& 
			(up = gpioRead(JOYSTICK_UP))			&& 
			(select = gpioRead(JOYSTICK_SELECT)) );
	
	if(!down)
		return JOYSTICK_DOWN;
	else if(!up)
		return JOYSTICK_UP;
	else if(!select)
		return JOYSTICK_SELECT;
	return -1;
}

int lcdGetOSSelection()
{
	if(!lcdReady)
		return 0;

	int selected = 0;
	int button = 0;

	while(button != JOYSTICK_SELECT)
	{
		usdelay(600000);
		lcdSelect(selected);	

		button = lcdGetJoystickButton();
		switch(button)
		{
			case JOYSTICK_DOWN: selected++; break;
			case JOYSTICK_UP:   selected--; break;
		}

		if(selected < 0)
			selected = MAX_OS - 1;
		else if(selected == MAX_OS)
			selected = 0;
	}

	return selected;
}

void lcdSelect(int OS)
{
	int y = MENU_TOP + bitmaps[TOP_LOADING]->height;
	int x = lcdHorizCenter(bitmaps[MIDDLE_WINDOWS_CE]->width);

	switch(OS)
	{
		case WINDOWS:	lcdDisplayBitmap(bitmaps[MIDDLE_WINDOWS_CE_SELECT], x, y);
						lcdDisplayBitmap(bitmaps[MIDDLE_OPEN_PDA], x, y + bitmaps[MIDDLE_WINDOWS_CE_SELECT]->height);
						break;
		case OPEN_PDA:	lcdDisplayBitmap(bitmaps[MIDDLE_WINDOWS_CE], x, y);
						lcdDisplayBitmap(bitmaps[MIDDLE_OPEN_PDA_SELECT], x, y + bitmaps[MIDDLE_WINDOWS_CE_SELECT]->height);
						break;
	}
}


int lcdGetButton()
{
	usdelay(600000);
	return lcdGetJoystickButton();
}
#endif

#ifdef PB1100
void lcdDisplayLoadingMenu()
{
	Bitmap* bmps[3];
	bmps[0] = bitmaps[TOP_LOADING];
	bmps[1] = bitmaps[MIDDLE_PLEASE_WAIT];
	bmps[2] = bitmaps[BOTTOM];

	lcdDisplayMenu(bmps, 3);
}

void lcdDisplayErrorMenu()
{
	Bitmap* bmps[3];
	bmps[0] = bitmaps[TOP_ERROR];
	bmps[1] = bitmaps[MIDDLE_CANNOT_FIND_FILE];
	bmps[2] = bitmaps[BOTTOM];

	lcdDisplayMenu(bmps, 3);
	printf("Press a key to continue\n");
	getc();
}
#endif



void lcdInit()
{
	framebuffer = au1100lcdInit();
	lcdReady = lcdLoadGraphics();
	lcdFill(10, 10, 10, 10, 0);
}

void lcdFill(int x, int y, int width, int height, unsigned short value)
{
	if(!lcdReady)
		return;

	unsigned short* address = lcdPixelAddress(x, y);

	int i, j;
	for(i = y; i < (y + height); ++i)
	{
		for(j = x; j < (x + width); ++j)
			*address++ = value;

		address += (LCD_WIDTH - width);
	}
}

void lcdFillDisplay(uint16 value)
{	
	if(!lcdReady)
		return;

	unsigned short* fb = (unsigned short*) framebuffer;
	int i;
	for(i = 0; i < LCD_WIDTH * LCD_HEIGHT; ++i)
		*fb++ = value;
}

unsigned short* lcdPixelAddress(int x, int y)
{
	unsigned short* address = framebuffer + (y * LCD_WIDTH) + x;
	return address;
}

int lcdHorizCenter(int width)
{
	return width > LCD_WIDTH ? 0 : (LCD_WIDTH / 2) - (width / 2);
}

int lcdVertCenter(int height)
{
	return height > LCD_HEIGHT ? 0 : (LCD_HEIGHT / 2) - (height / 2);
}


void lcdDisplayBitmap(Bitmap* bitmap, int x, int y)
{
	lcdDisplayMaskBitmap(bitmap, 0, x, y);
}

void lcdDisplayMaskBitmap(Bitmap* bitmap, Bitmap* mask, int x, int y)
{
	if(!lcdReady)
		return;

	unsigned short* address;
	unsigned short* bmp_data = &bitmap->dataStart;
	unsigned short* msk_data;
	if(mask)
		msk_data = &mask->dataStart;
	
	int i, j;
	int x_offset = 0;
	int x_max = bitmap->width;
	int y_offset = 0;
	int y_max = bitmap->height;

	if(y < 0)
		y_offset = 0 - y;

	if((y + bitmap->height) > LCD_HEIGHT)
		y_max = LCD_HEIGHT - y;

	if(x < 0)
		x_offset = 0 - x;

	if((x + bitmap->width) > LCD_WIDTH)
		x_max = LCD_WIDTH - x;

	if(x_offset < bitmap->width)
	{
		address = lcdPixelAddress(x_offset ? 0 : x, y_offset ? 0 : y);

		bmp_data += bitmap->width * y_offset;
		msk_data += bitmap->width * y_offset;

		for(i = y_offset; i < y_max; ++i)
		{
			if(mask == 0)
				memCopy(bmp_data + x_offset, address, 2*(x_max - x_offset));
			else
			{
				for(j = x_offset; j < x_max; ++j)
				{
					address[j] = bmp_data[j] & msk_data[j];
				}
			}
			
			bmp_data += bitmap->width;
			msk_data += bitmap->width;
			address += LCD_WIDTH;
		}
	}
}

void lcdVertSlide(Bitmap* bitmap, int x, int y_start, int y_end, int speed)
{
	lcdDiagSlide(bitmap, x, x, y_start, y_end, speed);

}

void lcdHorizSlide(Bitmap* bitmap, int y, int x_start, int x_end, int speed)
{
	lcdDiagSlide(bitmap, x_start, x_end, y, y, speed);
}

#if 1
void lcdDiagSlide(Bitmap* bitmap, int x_start, int x_end, int y_start, int y_end, int speed)
{
	if(!lcdReady)
		return;

	int x_dist = x_end - x_start;
	int y_dist = y_end - y_start;
	int x_mod, y_mod;

	int x_dir = (x_end - x_start) > 0;
	int y_dir = (y_end - y_start) > 0;
	
	x_mod = x_dist ? y_dist / x_dist : 1;
	y_mod = y_dist ? x_dist / y_dist : 1;
	if(x_mod == 0)
		x_mod = 1;
			
	if(y_mod == 0)
		y_mod = 1;

	lcdDisplayBitmap(bitmap, x_start, y_start);
	usdelay(speed);

	int i = 0;
	while(x_start != x_end || y_start != y_end)
	{
		if( i % x_mod == 0 && x_start != x_end)
			x_dir ? ++x_start : --x_start;

		if( i % y_mod == 0 && y_start != y_end)
			y_dir ? ++y_start : --y_start;

		lcdDisplayBitmap(bitmap, x_start, y_start);
		usdelay(speed);

		i++;
	}
		
}
#else		//If we had a floating-point co-processor...this should work
void lcdDiagSlide(Bitmap* bitmap, int x_start, int x_end, int y_start, int y_end, int speed)
{
	if(!lcdReady)
		return;

	int x_dist = x_end - x_start;
	int y_dist = y_end - y_start;
	int x_dir = x_dist > 0;
	int y_dir = y_dist > 0;

	if(x_dist < 0)
		x_dist *= -1;
	if(y_dist < 0)
		y_dist *= -1;

	double x = x_start;
	double y = y_start;
	double x_inc = 1;
	double y_inc = 1;

	if(x_dist > y_dist)
		y_inc = y_dist / x_dist;
	else if(y_dist > x_dist)
		x_inc = x_dist / y_dist;
	

	lcdDisplayBitmap(bitmap, x, y);
	usdelay(speed);

	int i = 0;
	while( (int)x != x_end || (int)y != y_end)
	{
		x = x_dir ? x + x_inc : x - x_inc;
		y = y_dir ? y + y_inc : y - y_inc;

		lcdDisplayBitmap(bitmap, (int)x, (int)y);
		usdelay(speed);

		i++;
	}
		
}
#endif

int lcdLoadGraphics()
{
	int i;
	uint32 address = _RESOURCE_ADDRESS_;

	for(i = 0; i < BITMAP_COUNT; ++i)
	{
		bitmaps[i] = (Bitmap*) address;
		if(bitmaps[i]->id != AU_BITMAP_ID)
			return 0;
		address += bitmaps[i]->fileSize;
	}

	return 1;
}

void lcdUpdateStatus()
{
	if(!lcdReady)
		return;

	lcdDisplayBitmap(bitmaps[STATUS_BAR + statusIndex], lcdHorizCenter(bitmaps[STATUS_BAR + statusIndex]->width), menu_y + menu_height + 1);
	statusIndex += statusDirection;	
	
	if(statusIndex == 0)
		statusDirection = 1;

	if(statusIndex == MAX_STATUS)
	{
		statusDirection = -1;
		statusIndex--;
	}
}

void lcdDisplayWelcomeScreen()
{
	if(!lcdReady)
		return;

	int arrow_x = lcdHorizCenter(bitmaps[AMD]->width + bitmaps[AMD_ARROW]->width) + bitmaps[AMD]->width;
	int x_dist =  arrow_x + bitmaps[AMD_ARROW]->width;
	int y_dist = LCD_HEIGHT - 10;
	int x_offset = 0;
	int y_offset = 0;

	if(x_dist > y_dist)
		x_offset = x_dist - y_dist;
	else
		y_offset = y_dist - x_dist;

	lcdFillDisplay(0);
	usdelay(10000);
	lcdDiagSlide(bitmaps[AMD_ARROW], 0 - bitmaps[AMD_ARROW]->width + x_offset, arrow_x, LCD_HEIGHT - y_offset, 10, 1000);
	lcdVertSlide(bitmaps[AMD], lcdHorizCenter(bitmaps[AMD]->width + bitmaps[AMD_ARROW]->width), LCD_HEIGHT, 10, 0);	
	lcdHorizSlide(bitmaps[BOARD_LOGO], 55, 0 - bitmaps[BOARD_LOGO]->width, lcdHorizCenter(bitmaps[BOARD_LOGO]->width), 1000);
}

void lcdDisplayNoImage()
{
	lcdDisplayErrorMenu();
}

void lcdDisplayEntryPoint(int entryPoint)
{

}

void lcdWhipeOn(Bitmap* bmp, Bitmap* msk, int x, int y)
{
	if(!lcdReady)
		return;

	unsigned short* topScan, *bottomScan;
	unsigned short* msk_data = &msk->dataStart;
	int i;
	
	for(i = 0; i < (bmp->width * bmp->height); ++i)
		msk_data[i] = 0x00;

	topScan = msk_data + (bmp->height / 2) * bmp->width;
	bottomScan = topScan;
	
	while(topScan >= msk_data || bottomScan < (msk_data + (bmp->width * bmp->height)))
	{
		lcdDisplayMaskBitmap(bmp, msk, x, y);

		for(i = 0; i < bmp->width; ++i)
		{
			if(topScan >= msk_data)
				topScan[i] = 0xFFFF;
			if(bottomScan < (msk_data + (bmp->width * bmp->height)))
				bottomScan[i] = 0xFFFF;
		}

		topScan -= bmp->width;
		bottomScan += bmp->width;
		//usdelay(speed);
	}
	
	lcdDisplayMaskBitmap(bmp, msk, x, y);
}

void lcdWhipeOff(Bitmap* bmp, Bitmap* msk, int x, int y)
{
	if(!lcdReady)
		return;

	unsigned short *topScan, *bottomScan, *middle;
	short* msk_data = &msk->dataStart;
	int i;
	
	for(i = 0; i < (bmp->width * bmp->height); ++i)
		msk_data[i] = 0xFFFF;

	middle = msk_data + (bmp->height / 2) * bmp->width;
	topScan = msk_data;
	bottomScan = msk_data + (bmp->height-1) * bmp->width;
	
	while(topScan < middle || bottomScan >= middle)
	{
		lcdDisplayMaskBitmap(bmp, msk, x, y);

		for(i = 0; i < bmp->width; ++i)
		{
			if(topScan < middle)
				topScan[i] = 0x00;
			if(bottomScan >= middle)
				bottomScan[i] = 0x00;
		}

		topScan += bmp->width;
		bottomScan -= bmp->width;
	}
	
	lcdDisplayMaskBitmap(bmp, msk, x, y);
}


void lcdDisplayMenu(Bitmap* bmps[], int bitmapCount)
{
	if(!lcdReady)
		return;

	lcdFill(menu_x, menu_y, menu_width, menu_height, 0x00);

	int i;
	menu_y = MENU_TOP;
	menu_height = 0;
	for(i = 0; i < bitmapCount && (bmps[i]->id == AU_BITMAP_ID); ++i)
	{
		menu_width = bmps[i]->width;
		menu_x = lcdHorizCenter(menu_width);
		lcdDisplayBitmap(bmps[i], menu_x, menu_y + menu_height);
		menu_height += bmps[i]->height;
	}
}

int lcdSpliceBitmaps(Bitmap* destination, Bitmap* bmps[], int bitmapCount)
{
	if(!lcdReady)
		return;

	int i;
	short* address = &destination->dataStart;
	destination->width = bmps[0]->width;
	destination->height = 0;

	for(i = 0; i < bitmapCount; ++i)
	{
		if(bmps[i]->id != AU_BITMAP_ID)
			return 0;
		if(bmps[i]->width != destination->width)
			return 0;
	
		destination->height += bmps[i]->height;

		memCopy(&bmps[i]->dataStart, address, (bmps[i]->width * bmps[i]->height) * 2);
		address += (bmps[i]->width * bmps[i]->height);
	}

	destination->fileSize = (uint32) sizeof(destination->id)	+
							sizeof(destination->fileSize)		+ 
							sizeof(destination->width)			+
							sizeof(destination->height)			+
							destination->width * destination->height * 2;

	return 1;
}

⌨️ 快捷键说明

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