Day10_界面叠加处理

界面叠加处理

①当我们一个界面在另外一个界面的上方,或者当我们鼠标移动到一个界面的上方,那么我们处于下面的界面必定会被覆盖,那么当上面的东西,移动走了以后,需要将下面的在修改回去
②如何区分界面谁在下,谁在上?
设定一个height,即高度权重,权重越大,则越高,越高则最后描绘他的图像,不就可以达到覆盖下面界面的效果了吗?
③那么可想而知,鼠标肯定是最上面的那个图层,桌面肯定是最下面的图层,其余窗口的话,height肯定需要上下浮动

一个图层的构成

//透明图层的结构体
struct SHEET
{
    unsigned char * pu8Buf;//记录图层上 所描绘画内容的地址
    int nBxSize;    //图层的整体大小 由 Bx * By 来表示
    int nBySize;
    int nVx0;//VX VY 表示图层在画面上 位置的坐标
    int nVy0;
    int nColInv;//透明色色号
    int nHeight;//图层高度
    int nFlags;//存放图层的 各种设定信息
};

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
{
    unsigned char *pu8Vram;//Video Ram 的地址
    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_CONTROL *pCTL, struct SHEET *pSheet, 
int Height);



//移动图层 不改变 图层高度 
void SheetSlide(struct SHEET_CONTROL *pCTL, struct SHEET *pSheet, 
int Vx0, int Vy0);

//释放 已使用图层的内存
void SheetFree(struct SHEET_CONTROL *pCTL, struct SHEET *pSheet);

//刷新图层显示
void SheetRefreshSub(struct SHEET_CONTROL *pCTL, int Vx0, int Vy0, 
int Vx1, int Vy1);

//刷新图层显示
void SheetRefresh(struct SHEET_CONTROL *pCTL, struct SHEET *pSheet, 
int Vx0, int Vy0, int Vx1, int Vy1);

#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(pCTL));

    //如果分配失败的话
    if(0 == pCTL)
    {
        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;//代表 没有使用过
    }


    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 SheetUpDown(struct SHEET_CONTROL *pCTL, struct SHEET *pSheet,
 int Height)
{
    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;
        }
        //就是要隐藏图层了
        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--;
        }
        //按新图层的信息 重新描绘画面
        SheetRefresh(pCTL, pSheet, pSheet->nVx0, pSheet->nVy0,
         pSheet->nVx0+pSheet->nBxSize, pSheet->nVy0+pSheet->nBySize);
    }
    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++;
        }

        //按新图层的信息 重新描绘画面
         SheetRefresh(pCTL, pSheet,pSheet->nVx0, pSheet->nVy0,
          pSheet->nVx0+pSheet->nBxSize, pSheet->nVy0+pSheet->nBySize);

    }

    return ;
}




//移动图层 不改变 图层高度 
void SheetSlide(struct SHEET_CONTROL *pCTL, struct SHEET *pSheet,
 int Vx0, int Vy0)
{
    int nOldVx0 = pSheet->nVx0;
    int nOldVy0 = pSheet->nVy0;

    pSheet->nVx0 = Vx0;
    pSheet->nVy0 = Vy0;

    //如果该图层 正在被使用
    if(0 <= pSheet->nHeight)
    {
        //按新图层的信息 重新描绘画面
        SheetRefreshSub(pCTL, nOldVx0, nOldVy0, 
        pSheet->nBxSize + nOldVx0, pSheet->nBySize + nOldVy0);
        SheetRefreshSub(pCTL, Vx0, Vy0, pSheet->nBxSize + Vx0, 
        pSheet->nBySize + Vy0);
    }

    return ;
}

//释放 已使用图层的内存
void SheetFree(struct SHEET_CONTROL *pCTL, struct SHEET *pSheet)
{
    if(0 <= pSheet->nHeight)
    {
        SheetUpDown(pCTL, pSheet, -1);
    }

    //未被使用
    pSheet->nFlags = 0;

    return;
}






//刷新图层显示
void SheetRefresh(struct SHEET_CONTROL *pCTL, struct SHEET *pSheet,
 int Bx0, int By0, int Bx1, int By1)
{
    //如果正在显示的话
    if (pSheet->nHeight >= 0)
    {
        SheetRefreshSub(pCTL, pSheet->nVx0+Bx0, pSheet->nVy0+By0, 
        pSheet->nVx0+Bx1, pSheet->nVy0+By1);
    }
    
}


//刷新图层显示
void SheetRefreshSub(struct SHEET_CONTROL *pCTL, int Vx0, int Vy0, 
int Vx1, int Vy1)
{
    int nHeight;
    int nBx, nBy;
    int nVx, nVy;
    int Bx0, By0, Bx1, By1;
    unsigned char * pu8Buf;
    unsigned char ucChar;
    unsigned char *Vram = pCTL->pu8Vram;
    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 = 0; nHeight <= pCTL->nTop; nHeight++)
    {
        pSheet = pCTL->sheets[nHeight];
        pu8Buf = pSheet->pu8Buf;


        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(Vx0 <= nVx && nVx < Vx1 && Vy0 <= nVy && nVy < Vy1)
                {
                    ucChar = pu8Buf[nBy * pSheet->nBxSize + nBx];

                    if(ucChar != pSheet->nColInv)
                    {
                        Vram[nVy * pCTL->nXsize + nVx] = ucChar;
                    }
                }
            }
        }
    }

    return ;
}

main.c

	struct SHEET_CONTROL *pSheetCtl;//图层控制结构体
	struct SHEET *pSheetBack;//背景
	struct SHEET *pSheetMouse;//鼠标
	unsigned char *pBufBack;//背景缓冲区
	unsigned char MouseColor[256];//鼠标的大小是16*16的

	//为图层控制器 分配空间 并且初始化 图层控制器
	pSheetCtl = SheetControlInit(MenMan, pAdd, nXsize, nYsize);
	//为背景分配图层
	pSheetBack = GetSheet(pSheetCtl);
	//为鼠标分配图层
	pSheetMouse = GetSheet(pSheetCtl);
	//为背景缓存分配缓冲区
	pBufBack = (unsigned char *)MemoryManagerMalloc4K
	(MenMan, nXsize*nYsize);
	//背景 没有透明色
	SheetSetBuf(pSheetBack, pBufBack, nXsize, nYsize, -1);
	//鼠标 透明色号 99 鼠标缓存在MouseColor
	SheetSetBuf(pSheetMouse, MouseColor, 16, 16, 99);
	//设置背景从0 0 开始
	SheetSlide(pSheetCtl, pSheetBack, 0 , 0);

	//设置鼠标从中间 开始
	SheetSlide(pSheetCtl, pSheetMouse, mx , my);
	//设定图层高度
	SheetUpDown(pSheetCtl, pSheetBack, 0);
	SheetUpDown(pSheetCtl, pSheetMouse, 1);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值