📄 lcdsim.c
字号:
/***************************************************************
REVISION LOG ENTRY
Revision By: ...
Revised on 2005-05-30 20:25:27
Comments: LCDSIM.c LCD模似显示屏...
Revised on 2005-09-3 15:23:27
1. 修改函数LCDSIM_FillRect在BPP大于八位时的BUG, 并增加加束开关, 提高矩形直填充速度.
2. 修改函数LCDSIM_SetPixelIndex, 在BPP在于八位时如果填充颜色索引与上一次相同, 则无须
则进行索引到RGB颜色值的转换, 这样大大提高了在矩形填充及类似大面积填充相同颜色时的速度.
3. 修正了LCDSIM_SetPixelIndex中记录填充象素的变量的存错误. 调色板的记录变量也如此, 已修正.
Revised on 2005-09-16 01:31:27
1. 增加LCDSIM_GetPixelIndex获取指定屏幕坐标点的颜色索引函数的说明,这个函数先前有BUG,导
至在光滑处理时在边缘光滑处的地方有红晕,这个BUG还会导致在启用MOUSE后MOUSE移经的区域不
能正常刷新.
2. 修改COLORREF2Index函数的BUG,这个函数的功能是将颜色值转变成索引,用于取屏幕中象素点
的颜色索引值.
***************************************************************/
#include "Common.h"
extern int xPosLCD, yPosLCD;
extern int rgbTransparent;
extern HWND hWndMain;
extern char LCDCaption[200];
extern int LCDWidth, LCDHeight;
extern HANDLE SimFileMap;
#define LCDColorBlackNum 4
#define LCDColorWhiteNum 4
#define SPACEBEFORELCDM 0x400 //表示映象起始地址与LCD显示内存之间的空间...
int LCDSIM_aLCDColorBlack[LCDColorBlackNum];
int LCDSIM_aLCDColorWhite[LCDColorWhiteNum] = {0xffffff, 0xffffff, 0xffffff, 0xffffff};
int XSize = 0, YSize = 0, VYSize = 0, VXSize = 0;
LPVOID pFix; //申请的内存映象开始地址...
LPVOID pSMemFix; //申请的内存映象开始地址...
LPVOID pSMemVar; //申请的用于LCD显存的起始映象地址pSMemFix+0x1000[为SPACEBEFORELCDM]...
LPVOID paaPixel; //申请的用于LCD显存的起始映象地址...
LPVOID pBitmapInfo; //映象中LCD中显示位图之调色板的映象起始地址pSMemFix+0x28...
DWORD FixedPalette = 0; //调色板最大可用的色彩数目...
int BPP = 8; //一个象素所占位数...
int NumColors = 0;
int LUT_ModifyCnt = 0;
int BytesPerLine = 0;
int ModifyCnt = 0;
LCD_tMouseState mouseMessage;
void SIM_SetLCDPos(int x, int y)
{
xPosLCD = x;
yPosLCD = y;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : SIM_SetTransColor
// 功能描述 : 设置透明色
// 参数 : int Color
// 返回值 :
//
///////////////////////////////////////////////////////////////////////
int SIM_SetTransColor(int Color)
{
int OldrgbTransparent = rgbTransparent;
rgbTransparent = Color;
return OldrgbTransparent;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : SIM_SetLCDColorBlack
// 功能描述 : 设置背景色.共可设置四种.
// 参数 : unsigned int Index
// 参数 : int Color
// 返回值 :
//
///////////////////////////////////////////////////////////////////////
int SIM_SetLCDColorBlack(unsigned int Index, int Color)
{
int ret = 0;
if(Index >=4) return ret;
ret = LCDSIM_aLCDColorBlack[Index];
LCDSIM_aLCDColorBlack[Index] = Color;
return ret;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : SIM_SetLCDColorWhite
// 功能描述 : 设置前景色....
// 参数 : unsigned int Index
// 参数 : int Color
// 返回值 :
//
///////////////////////////////////////////////////////////////////////
int SIM_SetLCDColorWhite(unsigned int Index, int Color)
{
int ret = 0;
if(Index >=4) return ret;
ret = LCDSIM_aLCDColorWhite[Index];
LCDSIM_aLCDColorWhite[Index] = Color;
return ret;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : LCDSIM_Init
// 功能描述 : 此函数负责初始化LCD所使用的内存映象...其中一块于用存调色板.
// : 一块用作显示屏幕..
// 参数 : void
// 返回值 : char*
//
///////////////////////////////////////////////////////////////////////
char* LCDSIM_Init(void)
{
char* lpret = 0;
int* lptemp = 0;
int i = 0;
int lpCount = 0;
do{
InitSMem();
if(pSMemFix == 0) break;
XSize = LCD_GetXSize() * LCD_GetXMag();
YSize = LCD_GetYSize() * LCD_GetYMag();
VXSize = LCD_GetVXSize();
VYSize = LCD_GetVYSize();
BPP = LCD_GetBitsPerPixel();
FixedPalette = LCD_GetFixedPalette();
NumColors = LCD_GetNumColors();
pFix = pSMemFix;
lptemp = (int*) pSMemFix;
for(i = 0; i < SPACEBEFORELCDM; i++)
{
*lptemp++ = 0;
}
strcpy((char*)pSMemFix, "emWin GSC Simulation");
lpCount = (XSize * YSize & 0xfffffff0)/4; //调整为被4整除...
lptemp = (int*) pSMemVar;
for(i = 0; i < lpCount; i++)
{
*lptemp++ = 0;
}
lpret = (char*)lptemp;
lpCount = XSize * YSize & 3; //初始化不足球4个字节的内存...
for(i = 0; i < lpCount; i++)
{
*((char*)lpret)++ = 0;
// __asm mov lpret, 0;
}
lpret = 0;
pBitmapInfo = (char*)pSMemFix + 0x100;
paaPixel = pSMemVar;
// 2005-6-5 15:18:39
lptemp =(int*)((char*)pSMemFix+0x20); //pSMemFix+0x20开始依次存放以下东西...
*lptemp++ = XSize;
*lptemp++ = YSize;
*lptemp++ = VXSize;
*lptemp++ = VYSize;
*lptemp++ = FixedPalette; //此处暂空闲...
*lptemp++ = BPP;
*lptemp++ = NumColors;
if(BPP <= 8){
BytesPerLine = (XSize + 3) & 0xFFFFFFFC; //一行多少个字节,BPP为8则一个字节表示一个象素
//否则,用四个字表示一个象素,+3是表示LCD显示屏左边与底边有空...
for(i = 0; i < NumColors; i++) //此处初始化调色板...
{
LCDSIM_SetLUTEntry(i, LCD_L0_Index2Color(i));
}
}
else{
BytesPerLine = (XSize* 4 + 3) & 0xFFFFFFFC; //一行多少个字节,BPP为8则一个字节表示一个象素
// BytesPerLine = (XSize + 3) * 4 + 3;
}
return 0;
}while(0);
lpret = "Could not alloc Server data ...";
return lpret;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : InitSMem
// 功能描述 : 初始化LCD所使用的内存映象, 首先是打开, 必须要注意的是
// : 一点是, 在UCGUI应用程序已经运行的情况下且模拟器也已经打开了,
// : 如果些时关掉原来的UCGUI应用程序而再开一个新的, 那么将会进行一次
// : 重新初始化, InitSMem会被再次调用, 此时无须再次映象...
// 参数 : void
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void InitSMem(void)
{
//HANDLE SimFileMap = 0;
if(SimFileMap != 0) return;
SimFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 1, "emWinLCDMap");
if(SimFileMap == 0){
SimFileMap = CreateFileMapping((HANDLE)0xffffffff, 0, PAGE_READWRITE, 0, 0x401000, "emWinLCDMap");
}
pSMemFix = MapViewOfFile(SimFileMap, SECTION_MAP_WRITE | SECTION_MAP_READ, 0, 0, 0x401000);
pSMemVar = (int*)pSMemFix + 0x400;
//if(SimFileMap) CloseHandle(SimFileMap);
}
/* 2005-6-2 23:58:54
#if !defined (LCD_PHYSCOLORS)
#if (LCD_BITSPERPIXEL == 1) | (LCD_BITSPERPIXEL == 2) | (LCD_BITSPERPIXEL == 4)
#ifndef LCD_FIXEDPALETTE
#define LCD_FIXEDPALETTE LCD_BITSPERPIXEL
#endif
#endif
#endif // defined (LCD_PHYSCOLORS)
*/
/* 2005-6-2 23:01:21
#if !defined (LCD_FIXEDPALETTE)
#if !defined (LCD_PHYSCOLORS)
#if LCD_BITSPERPIXEL == 8
#define LCD_FIXEDPALETTE 8666
#elif LCD_BITSPERPIXEL == 12
#define LCD_FIXEDPALETTE 444
#elif LCD_BITSPERPIXEL == 15
#define LCD_FIXEDPALETTE 555
#elif LCD_BITSPERPIXEL == 16
#define LCD_FIXEDPALETTE 565
#else
#define LCD_FIXEDPALETTE 0
#endif
#else
#define LCD_FIXEDPALETTE 0
#endif
#endif*/
//由上面的注释内容可以看出LCD_BITSPERPIXEL大于8时只有三种情况,444/555/565
/* 2005-6-10 0:20:02
LCD_COLOR LCD_Index2Color_444(int Index)
{
unsigned int r,g,b;
r = Index & 0xf;
g = (Index >> 4) & 0xf;
b = ((unsigned)Index >> 8) & 0xf;
r = r * 17;
g = g * 17;
b = b * 17;
return r + (g<<8) + (((U32)b)<<16);
}*/
//-FixedPalette表示RGB中,R与B对换...
#include "LCD_Protected.h"
///////////////////////////////////////////////////////////////////////
//
// 函数名 : Convert_Index16IntoIndex32
// 功能描述 : 将颜色索引值转为RGB颜色值, 如FixedPalette为444时, 可显示
// : 4096种颜色, 其索引值则为0-4095, 画象素函数中指定的不是RGB, 而
// : 是此索引值, 写入到LCD显示内存先, 要转为FixedPalette对应RGB值.
// : FixedPalette值不同, 转换也有小的差别的...
// : gui\ConvertColor\下面的几个文件专门用于此的...
// : 索引转换成RGB的基本原理------
// 参数 : int Index
// 返回值 : LCD_COLOR
//
///////////////////////////////////////////////////////////////////////
// 索引转换成RGB的基本原理------首先, 对于RGB三值, 由FixedPalette指定其每个位所占的
// 位数, 如为444则各4位. FixedPalette中指定能表示的RGB的范围分别为(R,G,B)1111/1111/1111,
// 即16(R)/16(G)/16(B). 则当索引值Index为444时, 则是RGB各值索引最大的时候, 由此即可分析,
// R,G,B三值要表示的颜色范围是0x00-0xff, 为了让有限的0-16的索引来表示0x00-0xff这些颜色
// 值, 那么当然只能是跳隔着来表示, 拿R来说, 最好是取值为(17*0, 17*1, 17*2, 17*3,.....17*15=248),
// 如此的话, 才能差不多在有限的16个索引值下将0xff种颜色最大程度的表示到(比较平均)...
// 同理, 对于FixedPalette为555时, 则R取值最好为(8*0, 8*1, 8*2, 8*3,.....8*31=243)
// 同理, 对于FixedPalette为565时, 则B取值最好为(4*0, 4*1, 4*2, 4*3,.....4*63=252)
// 知道这一点, 则对于以下函数的理解就非常容易...
LCD_COLOR Convert_Index16IntoIndex32(int Index)
{
// int convertColor = 0;
int r = 0, g = 0, b = 0;
LCD_COLOR convertColor = 0;
switch(FixedPalette){
case 444:
convertColor = LCD_Index2Color_444(Index);
break;
case 555:
convertColor = LCD_Index2Color_555(Index);
break;
case -555:
convertColor = LCD_Index2Color_M555(Index);
break;
case 565:
convertColor = LCD_Index2Color_565(Index);
break;
case -565:
convertColor = LCD_Index2Color_M555(Index);
break;
case -444: //无此项转换...
break;
}
// 2005-8-21 16:32:22
r = (convertColor & 0xff) << 16;
g = (convertColor & 0xff00);
b = (convertColor & 0xff0000)>>16;
convertColor = r | g | b;
return convertColor;
/* 2005-6-4 12:33:06
return INDEX2COLOR(Index); //此一句可以底上前面的N句...
*/
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : LCDSIM_SetPixelIndex
// 功能描述 : 最基本的画点函数...
// 参数 : int x[点x坐标]
// 参数 : int y[点y坐标]
// 参数 : int Index[颜色索引值]
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void LCDSIM_SetPixelIndex(int x, int y, int Index)
{
static int preIndex = 0, preLUT = 0, curLUT = 0, curColor = 0;
int pixPos = 0;
char* lptemp = 0;
if(paaPixel == 0) return;
if(BPP <= 8){
pixPos = y * BytesPerLine + x;
lptemp = (char*)paaPixel + pixPos;
*lptemp = Index;
}
else{
// 2005-8-27 13:04:52
lptemp = (char*)pFix + 0x40;
curLUT = *((int*)lptemp);
if(curLUT != preLUT){ //改变了调色板时, 一定要重新根据索引转颜色...
preLUT = curLUT;
preIndex = -1;
}
if(preIndex != Index){
curColor = Convert_Index16IntoIndex32(Index);
}
pixPos = y * BytesPerLine + x * 4;
lptemp = (char*)paaPixel + pixPos;
*(int*)lptemp = curColor;
preIndex = Index;
}
ModifyCnt++;
//映象是否成功申请...
if(pFix != 0){
lptemp = (char*)((char*)pFix + 0x3c);
*((int*)lptemp) = ModifyCnt;
// 2005-8-27 13:04:52, 以前错写一个字符进去, 应该写一INT进去...
//*lptemp = ModifyCnt;
}
}
//处理成只有0xff 0xff 0...0xff(256种)
// 0xff 0...0xff 0xff(256种)
// 0...0xff 0xff 0xff(256种)
///////////////////////////////////////////////////////////////////////
//
// 函数名 : LCDSIM_SetSubPixel
// 功能描述 : 此函数主要是为了处理RGB时, 二者为最强色, 另一着为0...0xff
// : value取值为256种, 颜色值由x%3 << 3来决定, 即x的3倍的点都显示
// : 同一种颜色(一条竖直线), 颜色值为Value | ~(0xff << (x%3 << 3))
// 参数 : int x
// 参数 : int y
// 参数 : U8 Value[0--255]
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void LCDSIM_SetSubPixel(int x, int y, U8 Value)
{
int pixPos = 0;
char* lptemp = 0;
if(BPP <= 0) return;
//(0xff << (x%3 << 3))求此反码...
Value = Value | ~(0xff << (x%3 << 3));
if(BPP > 8){
pixPos = y * BytesPerLine + x * 4;
(char*)paaPixel += pixPos;
*(int*)paaPixel = Value;
}
ModifyCnt++;
//映象是否成功申请...
if(pFix != 0){
lptemp = (char*)((char*)pFix + 0x3c);
*lptemp = ModifyCnt;
}
}
//计算一种颜色介于黑白之间的的对比度...
///////////////////////////////////////////////////////////////////////
//
// 函数名 : FilterColor
// 功能描述 : 这个函数是在设置调色板(LCDSIM_SetLUTEntry)时用到的, 主要用于
// : 用8位及8位以下来表示一个象素点时. 要求它对应颜色值, 只须求
// : 其于黑白之间一个比例值, 如果白为0xff, 黑为0x0,那么color本身就为颜色值,
// : 如果白为0x80, 黑为0x10, 那么[color]_R=(0x80-0x10)*color/255, 对于B,G原理相同
// : 但是, 在调用LCDSIM_SetLUTEntry(i, LCD_L0_Index2Color(i))这个来看, color其
// : 实是一个RGB颜色, 对FixedPalette为111时, 调色板中只须要八种颜色, 不须要256个
// : 选项, 八种为(0x000000[0], 0x0000ff[1], 0x00ff00[2], 0x00ffff[3], 0xff0000[4], 0xff00ff[5], 0xffff00[6], 0xffffff[7] )
// : 即调色板索引(0-7, 8-15, 16-24, ....248-255)对于FixedPalette为111来说是重复的...
// : 所以初始化调色板时, 要先调用LCD_L0_Index2Color(i)将Index转为颜色, 再与黑白成比
// : 例综合. 这样了就可对负所有实际使用调色板为2项,4项,8项,16项,256项的一个字节表示点的所有
// : 用到调色析的情况.
// 参数 : LCD_COLOR color[RGB颜色值]
// 参数 : LCD_COLOR colorBlack
// 参数 : LCD_COLOR colorWhite
// 返回值 : LCD_COLOR
//
///////////////////////////////////////////////////////////////////////
LCD_COLOR FilterColor(LCD_COLOR color, LCD_COLOR colorBlack, LCD_COLOR colorWhite)
{
int temp1 = 0, temp2 = 0, temp3 = 0;
// temp2 = 0xff * 0xcc / 0xff;
temp1 = (colorWhite & 0xff - colorBlack & 0xff) * (color & 0xff) / 0xff + (colorBlack & 0xff);
temp2 = ((colorWhite & 0xff00 - colorBlack & 0xff00) >> 8) * ((color & 0xff00) >> 8) / 0xff + (colorBlack & 0xff00);
temp3 = ((colorWhite & 0xff0000 - colorBlack & 0xff0000) >> 16) * ((color & 0xff0000) >> 16) / 0xff + (colorBlack & 0xff0000);
return temp1 | temp2 << 8 | temp3 << 16;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : LCDSIM_SetLUTEntry
// 功能描述 : 初始化象素点为8位及以下时, 要用到调色板来显示位图的情况.调色板为256项.
// : 只有真正用到8位表示一个点时才用满调色板.其余情况下,调色析值有重复出现.
// 参数 : U8 Pos
// 参数 : LCD_COLOR color
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void LCDSIM_SetLUTEntry(U8 Pos, LCD_COLOR color)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -