📄 e_motion.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: E_Motion.c
* Author: Robin.xjliu (eMail: xjliu@sunplus.com)
* Tel: 00885-028-87848688-5884
* Date: 2005-11-11
* Description: Motion control lib
* Reference:
* Version history:
*-----------------------------------------------------------------------------
* Version YYYY-MM-DD-INDEX Modified By Description
* 1.0.0 2005-11-11 xjliu Create
*
*****************************************************************************/
#include "Include/E_Motion.h"
MOTION MOTION_TABLE[MOTION_NUM_MAX]; //motion control table
LISTHEAD MOTION_FREE_LIST; //Free motion list
LISTHEAD MOTION_MALLOC_LIST; //motion priority list
/**
* E_InitMotion - initialize motion.
*/
void E_InitMotion(void)
{
U16 i;
for( i = 0; i < MOTION_NUM_MAX; i++ )
{
MOTION_TABLE[i].MtnList.prev = (LISTHEAD*)NULL;
MOTION_TABLE[i].MtnList.next = (LISTHEAD*)NULL;
MOTION_TABLE[i].nMtnInfo.W = 0;
MOTION_TABLE[i].pSprite = (SPRITE*)NULL;
MOTION_TABLE[i].pActionTbl = (ACTION*)NULL;
MOTION_TABLE[i].pActionProc = (void*)NULL;
}
INIT_LIST_HEAD(&MOTION_FREE_LIST);
INIT_LIST_HEAD(&MOTION_MALLOC_LIST);
for (i = 0; i < MOTION_NUM_MAX; i++)
{
list_add( &(MOTION_TABLE[i].MtnList), &MOTION_FREE_LIST);
}
}
/**
* E_AllocMotion - alloc motion.
* @pActionTbl:
* @nActionID:
* @x:
* @y:
* @nPri:
* @RETURN:
*/
MOTION* E_AllocMotion(const ACTION *pActionTbl,
U16 nActionID,
S16 x, S16 y,
U16 nPri)
{
MOTION *pMotion;
ACTION *pAction;
FRAME *pFrame;
LISTHEAD *pList;
#ifdef ARG_CHK_EN
if( pActionTbl == (ACTION*)NULL )
{
return (MOTION*)NULL;
}
#endif
//Check motion free list is empty or not
if (list_empty(&MOTION_FREE_LIST))
{
return (MOTION*)NULL;
}
pList = MOTION_FREE_LIST.next;
pMotion = List2Motion(pList);
list_del(pList); //delete assigned MOTION from Motion free list
pAction = (ACTION*)(pActionTbl + nActionID);
pFrame = (FRAME*)(pAction->pFrameTbl);
//set motion basic info
pMotion->pActionTbl = pActionTbl;
pMotion->pActionProc = pAction->pActionProc;
pMotion->nMtnInfo.B.MTN_ActionID = nActionID;
pMotion->nMtnInfo.B.MTN_FrameID = 0;
pMotion->nMtnInfo.B.MTN_DelayCnt = 0;
pMotion->pSprite = PPU_AllocSprite(pFrame, x, y, nPri);
//insert assigned motion to motion malloc list
list_add(pList, &MOTION_MALLOC_LIST);
return pMotion;
}
/**
* E_FreeMotion - free motion.
* @pMotion:
*/
void E_FreeMotion(MOTION *pMotion)
{
#ifdef ARG_CHK_EN
if (pMotion < &MOTION_TABLE[0] ||
pMotion >= &MOTION_TABLE[MOTION_NUM_MAX])
{
return;
}
#endif
list_del(&pMotion->MtnList);
PPU_FreeSprite(pMotion->pSprite);
//clear motion info
pMotion->MtnList.prev = (LISTHEAD*)NULL;
pMotion->MtnList.next = (LISTHEAD*)NULL;
pMotion->nMtnInfo.W = 0;
pMotion->pSprite = (SPRITE*)NULL;
pMotion->pActionTbl = (ACTION*)NULL;
pMotion->pActionProc = (void*)NULL;
//Add to Free Motion List
list_add(&pMotion->MtnList, &MOTION_FREE_LIST);
}
/**
* E_MotionProc - control motion, execute motion process.
*/
void E_MotionProc(void)
{
MOTION *pMotion;
ACTION *pAction;
SPRITE *pSprite;
LISTHEAD *pos, *pHead;
pHead = &MOTION_MALLOC_LIST;
list_for_each_prev(pos, pHead)
{
pMotion = List2Motion(pos);
pSprite = pMotion->pSprite;
pAction = (ACTION*)(pMotion->pActionTbl + pMotion->nMtnInfo.B.MTN_ActionID);
//检查此MOTION所挂栽的Action是否合法。
if( pAction==(ACTION*)NULL )
{
continue;
}
//检查此MOTION所挂载的SPRITE是否合法。
// if( pSprite==(SPRITE*)NULL )
// {
// continue;
// }
//检查此ACTION所挂载的FRAME是否合法。
// if( pAction->pFrameTbl==(FRAME*)NULL )
// {
// pMotion->pSprite->pFrame = (FRAME*)NULL;
// continue;
// }
//检查此MOTION所执行的ACTION所挂载的过程函数是否合法并执行。
if( pMotion->pActionProc != (void*)NULL )
{
(*pMotion->pActionProc)(pMotion);
}
pMotion->nMtnInfo.B.MTN_DelayCnt++;
if( pMotion->nMtnInfo.B.MTN_DelayCnt < pAction->nActInfo.B.ACT_Delay )
{
continue;
}
pMotion->nMtnInfo.B.MTN_DelayCnt = 0;
pMotion->nMtnInfo.B.MTN_FrameID++;
//check current action played end or not, if end, go to next action
if( pMotion->nMtnInfo.B.MTN_FrameID >= pAction->nActInfo.B.ACT_FrameNum )
{
pMotion->nMtnInfo.B.MTN_FrameID = 0;
pMotion->nMtnInfo.B.MTN_ActionID = pAction->nActInfo.B.ACT_NextActionID;
pAction = (ACTION*)(pMotion->pActionTbl + pMotion->nMtnInfo.B.MTN_ActionID);
pMotion->pActionProc = pAction->pActionProc;
}
pSprite = pMotion->pSprite;
pSprite->pFrame = (FRAME*)(pAction->pFrameTbl + pMotion->nMtnInfo.B.MTN_FrameID);
}
}
/**
* E_ChangeAction - change action.
* @pMotion:
* @nActionID:
*/
void E_ChangeAction(MOTION *pMotion, U16 nActionID)
{
ACTION *pAction;
SPRITE *pSprite;
pMotion->nMtnInfo.B.MTN_FrameID = 0;
pMotion->nMtnInfo.B.MTN_ActionID = nActionID;
pMotion->nMtnInfo.B.MTN_DelayCnt = 0;
//get new action
pAction = (ACTION*)(pMotion->pActionTbl + pMotion->nMtnInfo.B.MTN_ActionID);
pMotion->pActionProc = pAction->pActionProc;
pSprite = pMotion->pSprite;
pSprite->pFrame = (FRAME*)(pAction->pFrameTbl + pMotion->nMtnInfo.B.MTN_FrameID);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -