2016-01-27 00:51:34 chip
Page 1546
📢 PUBLIC
WinMain.c:
/*************************************************************************/
/** ItemList.cpp: Manages the list of game items. **/
/** (C)2013 nlited systems, Chip Doran **/
/*************************************************************************/
#include <Windows.h>
#include <d2d1.h>
#include <math.h>
#include "Util.h"
#include "MyD2D.h"
#include "Sprite.h"
#include "Globals.h"
#define ITEM_MAX 1000 //Limit the number of game items at any one time.
using namespace D2D1; //Direct2D version 1
class ItemList {
typedef int (ItemList::*LISTFUNC)(HITEM hItem);
public:
static ItemList *Ptr(HITEMS hItems);
static int Create(HITEMS *phItems, HGAME hGame);
int Destroy(void);
int SetArena(const RECT *prArena);
int GetArena(RECT *prArena);
int GetControl(UINT PlayerID, UINT *pCtrlState);
int Add(HITEM hItem);
int Remove(HITEM hItem);
int GetNext(HITEM hItem, HITEM *phNext);
int Update(UINT Tick);
int Draw(HIMAGE hImg);
//Data
UINT32 Signature;
private:
ItemList(void);
~ItemList(void);
int Create2(HGAME hGame);
int Iterate(const char *Tag, LISTFUNC pFunc);
int IterateUpdate(HITEM hItem);
int IterateCollision(HITEM hItem);
int IterateDraw(HITEM hItem);
//Data
HGAME hGame;
HIMAGE hImg;
UINT Tick;
RECT rArena;
struct ItemLink_s *pListHead;
struct ItemLink_s *pListTail;
};
static struct ItemLink_s *ItemPtr(HITEM hItem) {
struct ItemLink_s *pItem= (struct ItemLink_s*)hItem;
if(!hItem || IsBadPtr(pItem,sizeof(*pItem),BADPTR_RW) || pItem->Signature!=SIGNATURE_ITEM)
pItem= 0;
return(pItem);
}
/*************************************************************************/
/** Public interface **/
/*************************************************************************/
int ItemsCreate(HITEMS *phItems, HGAME hGame) {
if(IsBadPtr(phItems,sizeof(*phItems),BADPTR_WRITE))
return(ERR_BADPTR);
return(ItemList::Create(phItems,hGame));
}
int ItemsDestroy(HITEMS hItems) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
return(pItems->Destroy());
}
int ItemsSetArena(HITEMS hItems, const RECT *prArena) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
if(IsBadPtr(prArena,sizeof(*prArena),BADPTR_READ))
return(ERR_BADPTR);
return(pItems->SetArena(prArena));
}
int ItemsGetArena(HITEMS hItems, RECT *prArena) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
if(IsBadPtr(prArena,sizeof(*prArena),BADPTR_WRITE))
return(ERR_BADPTR);
return(pItems->GetArena(prArena));
}
int ItemsGetControl(HITEMS hItems, UINT PlayerID, UINT *pCtrlState) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
if(pCtrlState && IsBadPtr(pCtrlState,sizeof(*pCtrlState),BADPTR_WRITE))
return(ERR_BADPTR);
return(pItems->GetControl(PlayerID,pCtrlState));
}
int ItemsAdd(HITEMS hItems, HITEM hItem) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
return(pItems->Add(hItem));
}
int ItemsRemove(HITEMS hItems, HITEM hItem) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
return(pItems->Remove(hItem));
}
int ItemsGetNext(HITEMS hItems, HITEM hItem, HITEM *phNext) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
if(IsBadPtr(phNext,sizeof(*phNext),BADPTR_WRITE))
return(ERR_BADPTR);
return(pItems->GetNext(hItem,phNext));
}
int ItemsUpdate(HITEMS hItems, UINT Tick) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
return(pItems->Update(Tick));
}
int ItemsDraw(HITEMS hItems, HIMAGE hImg) {
ItemList *pItems= ItemList::Ptr(hItems);
if(!pItems)
return(ERR_BADHANDLE);
return(pItems->Draw(hImg));
}
/*************************************************************************/
/** Public internals **/
/*************************************************************************/
ItemList *ItemList::Ptr(HITEMS hItems) {
ItemList *pItems= (ItemList*)hItems;
if(!hItems || IsBadPtr(pItems,sizeof(*pItems),BADPTR_RW) || pItems->Signature!=SIGNATURE_ITEMS)
pItems= 0;
return(pItems);
}
int ItemList::Create(HITEMS *phItems, HGAME hGame) {
int Err= ERR_OK;
ItemList *pItems= new ItemList;
if(!pItems) {
Err= Error(ERR_NOMEM,__FUNCTION__": Unable to alloc %d.",sizeof(*pItems));
} else if(IsErr(Err= pItems->Create2(hGame))) {
delete pItems;
} else {
*phItems= (HITEMS)pItems;
}
return(Err);
}
int ItemList::Destroy(void) {
int Err= ERR_OK;
delete this;
return(Err);
}
int ItemList::SetArena(const RECT *prArena) {
rArena= *prArena;
return(ERR_OK);
}
int ItemList::GetArena(RECT *prArena) {
*prArena= rArena;
return(ERR_OK);
}
int ItemList::GetControl(UINT PlayerID, UINT *pCtrlState) {
return(GameGetControl(hGame,PlayerID,pCtrlState));
}
int ItemList::Add(HITEM hItem) {
int Err= ERR_OK;
struct ItemLink_s *pLink= ItemGetLink(hItem);
if(!pLink) {
Err= Error(ERR_BADHANDLE,__FUNCTION__": Bad hItem[%X]",hItem);
} else {
if(!pListHead) {
pListHead= pListTail= pLink;
} else {
pLink->pPrev= pListTail;
pListTail->pNext= pLink;
pListTail= pLink;
}
}
return(Err);
}
int ItemList::Remove(HITEM hItem) {
int Err= ERR_OK;
struct ItemLink_s *pLink= ItemGetLink(hItem);
if(!pLink) {
Err= Error(ERR_BADHANDLE,__FUNCTION__": Bad hItem[%X]",hItem);
} else {
if(pLink==pListHead)
pListHead= pLink->pNext;
else
pLink->pPrev->pNext= pLink->pNext;
if(pLink==pListTail)
pListTail= pLink->pPrev;
else
pLink->pNext->pPrev= pLink->pPrev;
}
return(Err);
}
int ItemList::GetNext(HITEM hItem, HITEM *phNext) {
int Err= ERR_OK;
struct ItemLink_s *pLink= ItemGetLink(hItem);
if(!hItem) {
*phNext= pListHead ? pListHead->hItem:0;
} else if(!pLink) {
Err= Warn(ERR_BADHANDLE,__FUNCTION__": Bad hItem[%X]",hItem);
} else {
*phNext= pLink->pNext ? pLink->pNext->hItem:0;
}
return(Err);
}
int ItemList::Update(UINT Tick) {
int Err= ERR_OK;
this->Tick= Tick;
if(IsErr(Err= Iterate("Move",&ItemList::IterateUpdate)))
Err= Warn(Err,__FUNCTION__": ItemUpdate() failed.");
if(IsErr(Err= Iterate("Collision",&ItemList::IterateCollision)))
Err= Warn(Err,__FUNCTION__": ItemCollision() failed.");
return(Err);
}
int ItemList::Draw(HIMAGE hImg) {
int Err= ERR_OK;
LISTFUNC pDraw= &ItemList::IterateDraw;
this->hImg= hImg;
Err= Iterate("Draw",pDraw);
return(Err);
}
/*************************************************************************/
/** Private internals **/
/*************************************************************************/
ItemList::ItemList(void) {
memset(this,0,sizeof(*this));
Signature= SIGNATURE_ITEMS;
}
ItemList::~ItemList(void) {
struct ItemLink_s *pItem,*pNext;
Signature|= SIGNATURE_INVALID;
for(pItem=pListHead;pItem;pItem=pNext) {
pNext= pItem->pNext;
MemFree(pItem);
}
}
int ItemList::Create2(HGAME hGame) {
int Err= ERR_OK;
this->hGame= hGame;
return(Err);
}
int ItemList::Iterate(const char *Tag, LISTFUNC pFunc) {
int Err2,Err= ERR_OK;
struct ItemLink_s *pItem,*pNext;
for(pItem=pListHead;pItem;pItem=pNext) {
pNext= pItem->pNext;
Err2= (this->*pFunc)(pItem->hItem); //Overly-clever C++ syntax
if(IsErr(Err2)) {
Err= Warn(Err2,__FUNCTION__": %s failed on item %X",Tag,pItem);
}
}
return(Err);
}
/*************************************************************************/
/** Individual items **/
/*************************************************************************/
int ItemList::IterateUpdate(HITEM hItem) {
int Err= ERR_OK;
if(IsErr(Err= ItemUpdate(hItem,(HITEMS)this,Tick)))
Warn(Err,__FUNCTION__": Update on item [%X] failed.",hItem);
return(Err);
}
int ItemList::IterateCollision(HITEM hItem) {
int Err= ERR_OK;
if(IsErr(Err= ItemCollision(hItem,(HITEMS)this)))
Warn(Err,__FUNCTION__": Collision on item [%X] failed.",hItem);
return(Err);
}
int ItemList::IterateDraw(HITEM hItem) {
int Err= ERR_OK;
if(IsErr(Err= ItemDraw(hItem,hImg)))
Warn(Err,__FUNCTION__": Draw on item [%X] failed.",hItem);
return(Err);
}
WebV7 (C)2018 nlited | Rendered by tikope in 46.803ms | 3.17.179.132