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

📄 ppu_sprite.c

📁 凌阳32位单片机开发的小游戏
💻 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 + -