📄 ppu_sprite.c
字号:
/******************************************************************************
*
* The information contained herein is the exclusive property of
* Sunplus Technology Co. And shall not be distributed, reproduced,
* or disclosed in whole in part without prior written permission.
*
* (C) COPYRIGHT 2005 SUNPLUS TECHNOLOGY CO.
* ALL RIGHTS RESERVED
*
* The entire notice above must be reproduced on all authorized copies.
*
*****************************************************************************/
/******************************************************************************
* Filename: PPU_Sprite.c
* Author: Robin.xjliu (eMail: xjliu@sunplus.com)
* Tel: 00885-028-87848688-5884
* Date: 2005-11-04
* Description: sprite control lib
* Reference:
* Version history:
*-----------------------------------------------------------------------------
* Version YYYY-MM-DD-INDEX Modified By Description
* 1.0.0 2005-11-04 xjliu Create
*
*****************************************************************************/
#include "Include/PPU_Sprite.h"
bool g_bShowSpriteFlag;
U16 g_nUsed_Cell_Count;
SPRITE SPRITE_TABLE[SPRITE_NUM_MAX]; //Sprite control table
LISTHEAD SPRITE_FREE_LIST; //Free sprite list
LISTHEAD SPRITE_PRI_LIST[SPRITE_PRI_MAX/2]; //Sprite Priority List
/**
* PPU_InitSprite - initialize sprite.
*/
void PPU_InitSprite(void)
{
U16 i;
PAINT_CELL *pPaintCell;
//initialize SPRITE_TABLE
for(i=0; i<SPRITE_NUM_MAX; i++)
{
SPRITE_TABLE[i].SprList.prev = (LISTHEAD*)NULL;
SPRITE_TABLE[i].SprList.next = (LISTHEAD*)NULL;
SPRITE_TABLE[i].nCtrlFlag = 0x00000000;
SPRITE_TABLE[i].stPos.x = 0;
SPRITE_TABLE[i].stPos.y = 0;
SPRITE_TABLE[i].pFrame = (FRAME*)NULL;
}
//initialize SPRITE_FREE_LIST, add all SPTITE into SPRITE_FREE_LIST
INIT_LIST_HEAD(&SPRITE_FREE_LIST);
for (i = 0; i < SPRITE_NUM_MAX; i++)
{
list_add_tail(&SPRITE_TABLE[i].SprList, &SPRITE_FREE_LIST);
}
//initialize SPRITE_PRI_LIST
for (i = 0; i < SPRITE_PRI_MAX/2; i++)
{
INIT_LIST_HEAD(&SPRITE_PRI_LIST[i]);
}
{//initialize cell register (pack function in the future)
pPaintCell = (PAINT_CELL*)(P_PPU_Sprite);
for(i=0; i<CELL_NUM_MAX; i++)
{
pPaintCell->SP_Attribute1.DW = 0;
pPaintCell->SP_Attribute2.DW = 0;
pPaintCell++; //add 8 byte
}
}
PPU_SetSP_BUF_SA(SP_PGT_ADDR); //get the sprite PGT data (Array Data)
PPU_SetSP_En(SP_ENABLE);
g_nUsed_Cell_Count = 0;
g_bShowSpriteFlag = false;
}
/**
* PPU_AllocSprite - alloc sprite.
* @pFrame:
* @x:
* @y:
* @nPri:
* @RETURN:
*/
SPRITE* PPU_AllocSprite( const FRAME *pFrame, S16 x, S16 y, U16 nPri )
{
SPRITE *pSprite;
LISTHEAD *pList, *pPriList;
#ifdef ARG_CHK_EN
if (pFrame == (FRAME*)NULL)
{
return (SPRITE*)NULL;
}
#endif
//Check sprite priority
if (nPri >= SPRITE_PRI_MAX)
{
nPri = SPRITE_PRI_MAX - 1;
}
//Check Sprite free list is empty or not
if (list_empty(&SPRITE_FREE_LIST))
{
return (SPRITE*)NULL;
}
pList = SPRITE_FREE_LIST.next;
pSprite = List2Sprite(pList);
list_del(pList); //delete assigned SPRITE from Sprite free list
//set sprite basic info
pSprite->stPos.x = x;
pSprite->stPos.y = y;
pSprite->nCtrlFlag = 0x00000000;
pSprite->pFrame = (FRAME*)pFrame;
//insert assigned sprite to priority list
pPriList = &SPRITE_PRI_LIST[(nPri>>1)];
if( (nPri&0x0001) == 1 )
{
list_add(pList, pPriList); //Add to head, so it will have higher Priority
}
else
{
list_add_tail(pList, pPriList); //Add to tail, so it will have lower Priority
}
return (pSprite);
}
/**
* PPU_FreeSprite - free sprite.
* @pSprite:
*/
void PPU_FreeSprite(SPRITE *pSprite)
{
#ifdef ARG_CHK_EN
if (pSprite < &SPRITE_TABLE[0]
|| pSprite >= &SPRITE_TABLE[SPRITE_NUM_MAX]
|| pSprite->pFrame ==(FRAME*)NULL)
{
return;
}
#endif
//Remove from Sprite Priority list
list_del(&pSprite->SprList);
//Clean SPRITE
pSprite->SprList.prev = (LISTHEAD*)NULL;
pSprite->SprList.next = (LISTHEAD*)NULL;
pSprite->nCtrlFlag = 0x00000000;
pSprite->stPos.x = 0;
pSprite->stPos.y = 0;
pSprite->pFrame = (FRAME*)NULL;
//Add to Free Sprite List
list_add(&pSprite->SprList, &SPRITE_FREE_LIST);
}
/**
* PPU_PaintSprite - set all cell register, paint all sprites.
*/
void PPU_PaintSprite(void)
{
LISTHEAD *pos, *pHead;
PAINT_CELL *pPaintCell;
SPRITE *pSprite;
FRAME *pFrame;
FRAME_CELL *pFrameCell;
U16 i, nCellCount;
S16 sScrX,sScrY; //screen coordinate
nCellCount = 0;
pPaintCell = (PAINT_CELL*)(P_PPU_Sprite);
for (pHead=&SPRITE_PRI_LIST[0]; pHead<=(&SPRITE_PRI_LIST[SPRITE_PRI_MAX/2]-1); pHead++)
{
list_for_each_prev(pos, pHead)
{
pSprite = List2Sprite(pos);
pFrame = pSprite->pFrame;
#ifdef ARG_CHK_EN
if( pFrame == (FRAME*)NULL )
{
continue;
}
#endif
sScrX = pSprite->stPos.x; //Sprite's screen X(Sprite's cg relative to Screen left-top corner)
sScrY = pSprite->stPos.y; //Sprite's screen Y(Sprite's cg relative to Screen left-top corner)
//check sprite overstep screen or not
if( (sScrX - pFrame->stOrgPos.x + pFrame->stSize.width) < 0 ||
(sScrX - pFrame->stOrgPos.x) > SCREEN_WIDTH ||
(sScrY - pFrame->stOrgPos.y + pFrame->stSize.height) < 0 ||
(sScrY - pFrame->stOrgPos.y) > SCREEN_HEIGHT )
{
continue;
}
//check paint cell numbers is CELL_NUM_MAX
if( nCellCount + pFrame->nCellNum >= CELL_NUM_MAX )
{
continue;
}
//paint sprite
pFrameCell = (FRAME_CELL*)pFrame->pFrameCellTbl;
for( i = 0; i < pFrame->nCellNum; i++ )
{
pPaintCell->SP_Attribute1.B.nChNum = pFrameCell->nPGTIndex;
pPaintCell->SP_Attribute1.B.sPosX = pFrameCell->sRefX + sScrX;
pPaintCell->SP_Attribute2.B.nAttribute = pFrame->pFrameInfo->W;
pPaintCell->SP_Attribute2.B.sPosY = pFrameCell->sRefY + sScrY;
pFrameCell++;
pPaintCell++;
nCellCount++;
}
}
}
//clear all no painted cell
for( i = nCellCount; i < g_nUsed_Cell_Count; i++ )
{
pPaintCell->SP_Attribute1.DW = 0;
pPaintCell->SP_Attribute2.DW = 0;
pPaintCell++;
}
g_nUsed_Cell_Count = nCellCount;
g_bShowSpriteFlag = false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -