问题
由于在刷新的时候,总是先刷新refresh范围内的背景图层,然后再刷新窗口图层,所以会造成闪烁,还有当鼠标设备放在窗口上面的时候,也会造成闪烁
解决
①pMap 一个和屏幕等大的字符数组,来存放当前屏幕的被哪些Sheet占据
当我们刷新图层的时候,需要遍历图层,只有pMap中有该图层,我们才刷新,否则不刷新
②每个图层都有自己的缓冲区,我们是先把要画的内容,写入缓冲区中,然后由该缓冲区写入缓存,refresh图层
Sheet.h
#ifndef __SHEET_H__
#define __SHEET_H__
#include "Memory.h"
//图层的处理函数
//最多256个 图层
#define MAX_SHEETS 256
//使用该图层
#define SHEET_USE 1
//透明图层的结构体
struct SHEET
{
unsigned char * pu8Buf;//记录图层上 所描绘画内容的地址
int nBxSize; //图层的整体大小 由 Bx * By 来表示
int nBySize;
int nVx0;//VX VY 表示图层在画面上 位置的坐标
int nVy0;
int nColInv;//透明色色号
int nHeight;//图层高度
int nFlags;//存放图层的 各种设定信息
struct SHEET_CONTROL *pCtl;
};
struct SHEET_CONTROL
{
unsigned char *pu8Vram;//Video Ram 的地址
unsigned char *pMap; //整个界面上 图层的分布
int nXsize;//X Y 代表画面的大小
int nYsize;
int nTop;//代表 最上面 图层的高度
struct SHEET *sheets[MAX_SHEETS];//SHEET的指针数组
struct SHEET sheets0[MAX_SHEETS];//指向 下面的结构体的地址
};
//初始化 透明图层 控制的结构体
struct SHEET_CONTROL * SheetControlInit(struct MEMORY_MAN *pTemp,
unsigned char *pu8Vram, int nXsize, int nYsize);
//取得新生成的 未使用图层
struct SHEET_CONTROL * GetSheet(struct SHEET_CONTROL *pCTL);
//设置图层的缓冲区大小 和 透明色的函数
void SheetSetBuf(struct SHEET *pSheet, unsigned char *u8Buf,
int nXsize, int nYsize, int nColInv);
//设定底板的高度
void SheetUpDown(struct SHEET *pSheet, int Height);
//移动图层 不改变 图层高度
void SheetSlide(struct SHEET *pSheet, int Vx0, int Vy0);
//释放 已使用图层的内存
void SheetFree(struct SHEET *pSheet);
//刷新图层显示
void SheetRefreshSub(struct SHEET_CONTROL *pCTL, int Vx0, int Vy0,
int Vx1, int Vy1, int nBegin, int nEnd);
//刷新图层显示
void SheetRefresh(struct SHEET *pSheet, int Bx0, int By0, int Bx1,
int By1);
//向map中写入图层号码
void SheetRefershMap(struct SHEET_CONTROL *pCTL, int Vx0, int Vy0,
int Vx1, int Vy1, int nBegin);
#endif
Sheet.c
#include "Sheet.h"
#include "Memory.h"
//初始化 透明图层 控制的结构体
struct SHEET_CONTROL * SheetControlInit(struct MEMORY_MAN *pTemp,
unsigned char *pu8Vram, int nXsize, int nYsize)
{
struct SHEET_CONTROL *pCTL;
int i;
//为结构体分配内存空间
pCTL = (struct SHEET_CONTROL *)MemoryManagerMalloc4K(pTemp,
sizeof(struct SHEET_CONTROL));
//如果分配失败的话
if(0 == pCTL)
{
goto err;
}
//整个界面的图层的分布
pCTL->pMap = (unsigned char *)MemoryManagerMalloc4K(pTemp,
nXsize*nYsize);
if(0 == pCTL->pMap)
{
MemoryManagerFree4K(pTemp, (int)pCTL,
sizeof(struct SHEET_CONTROL));
goto err;
}
//分配成功
pCTL->pu8Vram = pu8Vram;
pCTL->nXsize = nXsize;
pCTL->nYsize = nYsize;
pCTL->nTop = -1; //代表 一个图层都没有
for(i = 0; i < MAX_SHEETS; i++)
{
pCTL->sheets0[i].nFlags = 0;//代表 没有使用过
pCTL->sheets0[i].pCtl = pCTL;
}
err:
return pCTL;
}
//取得新生成的 未使用图层
struct SHEET_CONTROL * GetSheet(struct SHEET_CONTROL *pCTL)
{
struct SHEET *pSheet;
int i;
for(i = 0; i < MAX_SHEETS; i++)
{
//该图层 未被使用
if(0 == pCTL->sheets0[i].nFlags)
{
pSheet = &(pCTL->sheets0[i]);
//标记为使用过了
pSheet->nFlags = SHEET_USE;
pSheet->nHeight = -1;//表示隐藏 图层高度还未设置
return pSheet;
}
}
return 0;
}
//设置图层的缓冲区大小 和 透明色的函数
void SheetSetBuf(struct SHEET *pSheet, unsigned char *pu8Buf,
int nXsize, int nYsize, int nColInv)
{
pSheet->pu8Buf = pu8Buf;
pSheet->nBxSize = nXsize;
pSheet->nBySize = nYsize;
pSheet->nColInv = nColInv;
return ;
}
//移动图层 不改变 图层高度
void SheetSlide(struct SHEET *pSheet, int Vx0, int Vy0)
{
struct SHEET_CONTROL *pCTL = pSheet->pCtl;
int nOldVx0 = pSheet->nVx0;
int nOldVy0 = pSheet->nVy0;
pSheet->nVx0 = Vx0;
pSheet->nVy0 = Vy0;
//如果该图层 正在被使用
if(pSheet->nHeight >= 0)
{
SheetRefershMap(pCTL, nOldVx0, nOldVy0, pSheet->nBxSize
+ nOldVx0, pSheet->nBySize + nOldVy0, 0);
SheetRefershMap(pCTL,Vx0, Vy0, pSheet->nBxSize + Vx0,
pSheet->nBySize + Vy0, pSheet->nHeight);
//按新图层的信息 重新描绘画面
SheetRefreshSub(pCTL, nOldVx0, nOldVy0, pSheet->nBxSize
+ nOldVx0, pSheet->nBySize + nOldVy0, 0, pSheet->nHeight-1);
SheetRefreshSub(pCTL, Vx0, Vy0, pSheet->nBxSize + Vx0,
pSheet->nBySize + Vy0, pSheet->nHeight, pSheet->nHeight);
}
return ;
}
//释放 已使用图层的内存
void SheetFree( struct SHEET *pSheet)
{
if(0 <= pSheet->nHeight)
{
SheetUpDown(pSheet, -1);
}
//未被使用
pSheet->nFlags = 0;
return;
}
//刷新图层显示
void SheetRefresh(struct SHEET *pSheet, int Bx0, int By0, int Bx1,
int By1)
{
//如果正在显示的话
if (pSheet->nHeight >= 0)
{
SheetRefreshSub(pSheet->pCtl ,pSheet->nVx0+Bx0,
pSheet->nVy0+By0, pSheet->nVx0+Bx1, pSheet->nVy0+By1,
pSheet->nHeight, pSheet->nHeight);
}
}
//向map中写入图层号码
void SheetRefershMap(struct SHEET_CONTROL *pCTL, int Vx0, int Vy0,
int Vx1, int Vy1, int nBegin)
{
int nHeight;
int nBx, nBy;
int nVx, nVy;
int Bx0, By0, Bx1, By1;
unsigned char * pu8Buf;
unsigned char u8SheetId;
unsigned char *pMap = pCTL->pMap;
struct SHEET *pSheet;
if(0 > Vx0) {Vx0 = 0;}
if(0 > Vy0) {Vy0 = 0;}
if(Vx1 > pCTL->nXsize) {Vx1 = pCTL->nXsize;}
if(Vy1 > pCTL->nYsize) {Vy1 = pCTL->nYsize;}
//描绘出需要改变的的图层
for(nHeight = nBegin; nHeight <= pCTL->nTop; nHeight++)
{
pSheet = pCTL->sheets[nHeight];//当前该图层的首地址
pu8Buf = pSheet->pu8Buf;
u8SheetId = pSheet - (pCTL->sheets0);
//进行了减法计算的地址 当做图层号码使用
Bx0 = Vx0 - pSheet->nVx0;
By0 = Vy0 - pSheet->nVy0;
Bx1 = Vx1 - pSheet->nVx0;
By1 = Vy1 - pSheet->nVy0;
if(Bx0 < 0) {Bx0 = 0;}
if(By0 < 0) {By0 = 0;}
if(Bx1 > pSheet->nBxSize) {Bx1 = pSheet->nBxSize;}
if(By1 > pSheet->nBySize) {By1 = pSheet->nBySize;}
for(nBy = By0; nBy < By1; nBy++)
{
nVy = pSheet->nVy0 + nBy;
for(nBx = Bx0; nBx < Bx1; nBx++)
{
nVx = pSheet->nVx0 + nBx;
if(pu8Buf[nBy * pSheet->nBxSize + nBx] !=
pSheet->nColInv)
{
pMap[nVy * pCTL->nXsize + nVx] = u8SheetId;
}
}
}
}
return ;
}
//刷新图层显示 设定了起始图层 和 结束图层
void SheetRefreshSub(struct SHEET_CONTROL *pCTL, int Vx0, int Vy0,
int Vx1, int Vy1, int nBegin, int nEnd)
{
int nHeight;
int nBx, nBy;
int nVx, nVy;
int Bx0, By0, Bx1, By1;
unsigned char * pu8Buf;
//unsigned char ucChar;
unsigned char *pMap = pCTL->pMap;
unsigned char *Vram = pCTL->pu8Vram;
unsigned char u8SheetId;
struct SHEET *pSheet;
if(0 > Vx0) {Vx0 = 0;}
if(0 > Vy0) {Vy0 = 0;}
if(Vx1 > pCTL->nXsize) {Vx1 = pCTL->nXsize;}
if(Vy1 > pCTL->nYsize) {Vy1 = pCTL->nYsize;}
//描绘出需要改变的的图层
for(nHeight = nBegin; nHeight <= nEnd; nHeight++)
{
pSheet = pCTL->sheets[nHeight];
pu8Buf = pSheet->pu8Buf;
u8SheetId = pSheet - (pCTL->sheets0);
//进行了减法计算的地址 当做图层号码使用
Bx0 = Vx0 - pSheet->nVx0;
By0 = Vy0 - pSheet->nVy0;
Bx1 = Vx1 - pSheet->nVx0;
By1 = Vy1 - pSheet->nVy0;
if(Bx0 < 0) {Bx0 = 0;}
if(By0 < 0) {By0 = 0;}
if(Bx1 > pSheet->nBxSize) {Bx1 = pSheet->nBxSize;}
if(By1 > pSheet->nBySize) {By1 = pSheet->nBySize;}
for(nBy = By0; nBy < By1; nBy++)
{
nVy = pSheet->nVy0 + nBy;
for(nBx = Bx0; nBx < Bx1; nBx++)
{
nVx = pSheet->nVx0 + nBx;
//如果Map中的SheetId 和 当前图层的SheetId 一致
//那我们就在屏幕上描画
if(pMap[nVy * pCTL->nXsize + nVx] == u8SheetId)
{
Vram[nVy * pCTL->nXsize + nVx] =
pu8Buf[nBy * pSheet->nBxSize + nBx];
}
}
}
}
return ;
}
void SheetUpDown(struct SHEET *pSheet, int Height)
{
struct SHEET_CONTROL *pCTL = pSheet->pCtl;
int h;
int nOldHeight = pSheet->nHeight;
pSheet->nHeight = Height;
//如果指定的高度 太高 或者 过低 则 进行修正
if(Height > (pCTL->nTop + 1))
{
Height = pCTL->nTop + 1;
}
if(Height < -1)
{
Height = -1;
}
//进行sheets的重新排列
//如果新设置的高度 比从前 低的话
if(nOldHeight > Height)
{
if(Height >= 0)
{
//向后 搬迁
for(h = nOldHeight; h > Height; h--)
{
pCTL->sheets[h] = pCTL->sheets[h-1];
pCTL->sheets[h]->nHeight = h;
}
pCTL->sheets[Height] = pSheet;
SheetRefershMap(pCTL, pSheet->nVx0, pSheet->nVy0,
pSheet->nVx0+pSheet->nBxSize,
pSheet->nVy0+pSheet->nBySize, Height+1);
//按新图层的信息 重新描绘画面
SheetRefreshSub(pCTL, pSheet->nVx0, pSheet->nVy0,
pSheet->nVx0+pSheet->nBxSize,
pSheet->nVy0+pSheet->nBySize, Height+1, nOldHeight);
}
//就是要隐藏图层了
else
{
if(pCTL->nTop > nOldHeight)
{
for(h = nOldHeight; h < pCTL->nTop; h++)
{
pCTL->sheets[h] = pCTL->sheets[h+1];
pCTL->sheets[h]->nHeight = h;
}
}
pCTL->nTop--;
SheetRefershMap(pCTL, pSheet->nVx0, pSheet->nVy0,
pSheet->nVx0+pSheet->nBxSize,
pSheet->nVy0+pSheet->nBySize, 0);
//按新图层的信息 重新描绘画面
SheetRefreshSub(pCTL, pSheet->nVx0, pSheet->nVy0,
pSheet->nVx0+pSheet->nBxSize,
pSheet->nVy0+pSheet->nBySize, 0, nOldHeight-1);
}
}
else if(nOldHeight < Height)//比以前高
{
if(nOldHeight >= 0)//以前 就是显示状态
{
for(h = nOldHeight; h < Height; h++)
{
pCTL->sheets[h] = pCTL->sheets[h+1];
pCTL->sheets[h]->nHeight = h;
}
pCTL->sheets[h] = pSheet;
}
else//由隐藏状态 转变为 显示状态
{
for(h = pCTL->nTop; h >= Height; h--)
{
pCTL->sheets[h+1] = pCTL->sheets[h];
pCTL->sheets[h+1]->nHeight = h+1;
}
pCTL->sheets[Height] = pSheet;
pCTL->nTop++;
}
SheetRefershMap(pCTL, pSheet->nVx0, pSheet->nVy0,
pSheet->nVx0+pSheet->nBxSize,
pSheet->nVy0+pSheet->nBySize, Height);
//按新图层的信息 重新描绘画面
SheetRefreshSub(pCTL, pSheet->nVx0, pSheet->nVy0,
pSheet->nVx0+pSheet->nBxSize,
pSheet->nVy0+pSheet->nBySize, Height, Height);
}
return ;
}
758

被折叠的 条评论
为什么被折叠?



