TINSEL: Correctly handle the pDispList OBJECT linked lists, i.e. use OBJECT** for a pointer to the head.
Signed-off-by: Max Horn <max@quendi.de>
This commit is contained in:
parent
9c01c38512
commit
f143668db4
10 changed files with 32 additions and 48 deletions
|
@ -149,7 +149,7 @@ int PlayfieldGetCenterX(int which) {
|
|||
* @param which Which playfield
|
||||
*/
|
||||
|
||||
OBJECT *GetPlayfieldList(int which) {
|
||||
OBJECT **GetPlayfieldList(int which) {
|
||||
PLAYFIELD *pPlayfield; // pointer to relavent playfield
|
||||
|
||||
// make sure there is a background
|
||||
|
@ -162,22 +162,7 @@ OBJECT *GetPlayfieldList(int which) {
|
|||
pPlayfield = pCurBgnd->fieldArray + which;
|
||||
|
||||
// return the display list pointer for this playfield
|
||||
//
|
||||
// HACK: We pretend that pPlayfield is an OBJECT here, by explicitly
|
||||
// casting a pointer to it (resp. to its first member) to an OBJECT
|
||||
// pointer.
|
||||
// Of course it isn't, but its first member is pDispList, an OBJECT
|
||||
// pointer, just like the first member of an OBJECT is pNext, also
|
||||
// an OBJECT pointer. This (classic) trick allows us to use
|
||||
// pPlayfield as a fake anchor element for the linked list of
|
||||
// objects pDispList points to, which in turn simplifies some list
|
||||
// manipulation code. Alas, this is prone to confuse aliasing
|
||||
// analysis in compilers, and also silly developers like myself ;).
|
||||
// So at the very least, I figured we should document this trick
|
||||
// here explicitly.
|
||||
// Personally, I would prefer if we got rid of this trick, e.g. by
|
||||
// introducing an explicit anchor element.
|
||||
return (OBJECT *)&pPlayfield->pDispList;
|
||||
return &pPlayfield->pDispList;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,10 +202,10 @@ void DrawBackgnd() {
|
|||
pPlay->bMoved = true;
|
||||
|
||||
// sort the display list for this background - just in case somebody has changed object Z positions
|
||||
SortObjectList((OBJECT *)&pPlay->pDispList);
|
||||
SortObjectList(&pPlay->pDispList);
|
||||
|
||||
// generate clipping rects for all objects that have moved etc.
|
||||
FindMovingObjects((OBJECT *)&pPlay->pDispList, &ptWin,
|
||||
FindMovingObjects(&pPlay->pDispList, &ptWin,
|
||||
&pPlay->rcClip, false, pPlay->bMoved);
|
||||
|
||||
// clear playfield moved flag
|
||||
|
@ -247,8 +232,7 @@ void DrawBackgnd() {
|
|||
|
||||
if (IntersectRectangle(rcPlayClip, pPlay->rcClip, *r))
|
||||
// redraw all objects within this clipping rect
|
||||
UpdateClipRect((OBJECT *)&pPlay->pDispList,
|
||||
&ptWin, &rcPlayClip);
|
||||
UpdateClipRect(&pPlay->pDispList, &ptWin, &rcPlayClip);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ void PlayfieldGetPos( // Returns the xy position of the specified playfield in
|
|||
int PlayfieldGetCenterX( // Returns the xy position of the specified playfield in the current background
|
||||
int which); // which playfield
|
||||
|
||||
OBJECT *GetPlayfieldList( // Returns the display list for the specified playfield
|
||||
OBJECT **GetPlayfieldList( // Returns the display list for the specified playfield
|
||||
int which); // which playfield
|
||||
|
||||
void KillPlayfieldList( // Kills all the objects on the display list for the specified playfield
|
||||
|
|
|
@ -105,10 +105,10 @@ static bool LooseIntersectRectangle(const Common::Rect &pSrc1, const Common::Rec
|
|||
* @param bNoVelocity When reset, objects pos is updated with velocity
|
||||
* @param bScrolled) When set, playfield has scrolled
|
||||
*/
|
||||
void FindMovingObjects(OBJECT *pObjList, Common::Point *pWin, Common::Rect *pClip, bool bNoVelocity, bool bScrolled) {
|
||||
void FindMovingObjects(OBJECT **pObjList, Common::Point *pWin, Common::Rect *pClip, bool bNoVelocity, bool bScrolled) {
|
||||
OBJECT *pObj; // object list traversal pointer
|
||||
|
||||
for (pObj = pObjList->pNext; pObj != NULL; pObj = pObj->pNext) {
|
||||
for (pObj = *pObjList; pObj != NULL; pObj = pObj->pNext) {
|
||||
if (!bNoVelocity) {
|
||||
// we want to add velocities to objects position
|
||||
|
||||
|
@ -203,7 +203,7 @@ void MergeClipRect() {
|
|||
* @param pWin Window top left position
|
||||
* @param pClip Pointer to clip rectangle
|
||||
*/
|
||||
void UpdateClipRect(OBJECT *pObjList, Common::Point *pWin, Common::Rect *pClip) {
|
||||
void UpdateClipRect(OBJECT **pObjList, Common::Point *pWin, Common::Rect *pClip) {
|
||||
int x, y, right, bottom; // object corners
|
||||
int hclip, vclip; // total size of object clipping
|
||||
DRAWOBJECT currentObj; // filled in to draw the current object in list
|
||||
|
@ -212,7 +212,7 @@ void UpdateClipRect(OBJECT *pObjList, Common::Point *pWin, Common::Rect *pClip)
|
|||
// Initialise the fields of the drawing object to empty
|
||||
memset(¤tObj, 0, sizeof(DRAWOBJECT));
|
||||
|
||||
for (pObj = pObjList->pNext; pObj != NULL; pObj = pObj->pNext) {
|
||||
for (pObj = *pObjList; pObj != NULL; pObj = pObj->pNext) {
|
||||
if (pObj->flags & DMA_ABS) {
|
||||
// object position is absolute
|
||||
x = fracToInt(pObj->xPos);
|
||||
|
|
|
@ -55,7 +55,7 @@ bool UnionRectangle( // Creates the union of two rectangles
|
|||
const Common::Rect &pSrc2); // a source rectangle
|
||||
|
||||
void FindMovingObjects( // Creates clipping rectangles for all the objects that have moved on the specified object list
|
||||
OBJECT *pObjList, // playfield display list to draw
|
||||
OBJECT **pObjList, // playfield display list to draw
|
||||
Common::Point *pWin, // playfield window top left position
|
||||
Common::Rect *pClip, // playfield clipping rectangle
|
||||
bool bVelocity, // when set, objects pos is updated with velocity
|
||||
|
@ -64,7 +64,7 @@ void FindMovingObjects( // Creates clipping rectangles for all the objects that
|
|||
void MergeClipRect(); // Merges any clipping rectangles that overlap
|
||||
|
||||
void UpdateClipRect( // Redraws all objects within this clipping rectangle
|
||||
OBJECT *pObjList, // object list to draw
|
||||
OBJECT **pObjList, // object list to draw
|
||||
Common::Point *pWin, // window top left position
|
||||
Common::Rect *pClip); // pointer to clip rectangle
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ OBJECT *MultiInitObject(const MULTI_INIT *pInitTbl) {
|
|||
|
||||
*/
|
||||
|
||||
void MultiInsertObject(OBJECT *pObjList, OBJECT *pInsObj) {
|
||||
void MultiInsertObject(OBJECT **pObjList, OBJECT *pInsObj) {
|
||||
// validate object pointer
|
||||
assert(isValidObject(pInsObj));
|
||||
|
||||
|
@ -111,7 +111,7 @@ void MultiInsertObject(OBJECT *pObjList, OBJECT *pInsObj) {
|
|||
* @param pMultiObj Multi-part object to be deleted
|
||||
*/
|
||||
|
||||
void MultiDeleteObject(OBJECT *pObjList, OBJECT *pMultiObj) {
|
||||
void MultiDeleteObject(OBJECT **pObjList, OBJECT *pMultiObj) {
|
||||
// validate object pointer
|
||||
assert(isValidObject(pMultiObj));
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@ OBJECT *MultiInitObject( // Initialise a multi-part object
|
|||
const MULTI_INIT *pInitTbl); // pointer to multi-object initialisation table
|
||||
|
||||
void MultiInsertObject( // Insert a multi-part object onto a object list
|
||||
OBJECT *pObjList, // list to insert multi-part object onto
|
||||
OBJECT **pObjList, // list to insert multi-part object onto
|
||||
OBJECT *pInsObj); // head of multi-part object to insert
|
||||
|
||||
void MultiDeleteObject( // Delete all the pieces of a multi-part object
|
||||
OBJECT *pObjList, // list to delete multi-part object from
|
||||
OBJECT **pObjList, // list to delete multi-part object from
|
||||
OBJECT *pMultiObj); // multi-part object to be deleted
|
||||
|
||||
void MultiHideObject( // Hide a multi-part object
|
||||
|
|
|
@ -162,13 +162,13 @@ void CopyObject(OBJECT *pDest, OBJECT *pSrc) {
|
|||
* @param pInsObj Object to insert
|
||||
*/
|
||||
|
||||
void InsertObject(OBJECT *pObjList, OBJECT *pInsObj) {
|
||||
OBJECT *pPrev, *pObj; // object list traversal pointers
|
||||
void InsertObject(OBJECT **pObjList, OBJECT *pInsObj) {
|
||||
OBJECT **pAnchor, *pObj; // object list traversal pointers
|
||||
|
||||
// validate object pointer
|
||||
assert(isValidObject(pInsObj));
|
||||
|
||||
for (pPrev = pObjList, pObj = pObjList->pNext; pObj != NULL; pPrev = pObj, pObj = pObj->pNext) {
|
||||
for (pAnchor = pObjList, pObj = *pAnchor; pObj != NULL; pAnchor = &pObj->pNext, pObj = *pAnchor) {
|
||||
// check Z order
|
||||
if (pInsObj->zPos < pObj->zPos) {
|
||||
// object Z is lower than list Z - insert here
|
||||
|
@ -182,9 +182,9 @@ void InsertObject(OBJECT *pObjList, OBJECT *pInsObj) {
|
|||
}
|
||||
}
|
||||
|
||||
// insert obj between pPrev and pObj
|
||||
// insert obj between pAnchor and pObj
|
||||
pInsObj->pNext = pObj;
|
||||
pPrev->pNext = pInsObj;
|
||||
*pAnchor = pInsObj;
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,8 +194,8 @@ void InsertObject(OBJECT *pObjList, OBJECT *pInsObj) {
|
|||
* @param pObjList List to delete object from
|
||||
* @param pDelObj Object to delete
|
||||
*/
|
||||
void DelObject(OBJECT *pObjList, OBJECT *pDelObj) {
|
||||
OBJECT *pPrev, *pObj; // object list traversal pointers
|
||||
void DelObject(OBJECT **pObjList, OBJECT *pDelObj) {
|
||||
OBJECT **pAnchor, *pObj; // object list traversal pointers
|
||||
const Common::Rect rcScreen(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
// validate object pointer
|
||||
|
@ -207,7 +207,7 @@ void DelObject(OBJECT *pObjList, OBJECT *pDelObj) {
|
|||
assert(numObj >= 0);
|
||||
#endif
|
||||
|
||||
for (pPrev = pObjList, pObj = pObjList->pNext; pObj != NULL; pPrev = pObj, pObj = pObj->pNext) {
|
||||
for (pAnchor = pObjList, pObj = *pAnchor; pObj != NULL; pAnchor = &pObj->pNext, pObj = *pAnchor) {
|
||||
if (pObj == pDelObj) {
|
||||
// found object to delete
|
||||
|
||||
|
@ -217,7 +217,7 @@ void DelObject(OBJECT *pObjList, OBJECT *pDelObj) {
|
|||
}
|
||||
|
||||
// make PREV next = OBJ next - removes OBJ from list
|
||||
pPrev->pNext = pObj->pNext;
|
||||
*pAnchor = pObj->pNext;
|
||||
|
||||
// place free list in OBJ next
|
||||
pObj->pNext = pFreeObjects;
|
||||
|
@ -245,12 +245,12 @@ void DelObject(OBJECT *pObjList, OBJECT *pDelObj) {
|
|||
* Sort the specified object list in Z Y order.
|
||||
* @param pObjList List to sort
|
||||
*/
|
||||
void SortObjectList(OBJECT *pObjList) {
|
||||
void SortObjectList(OBJECT **pObjList) {
|
||||
OBJECT *pPrev, *pObj; // object list traversal pointers
|
||||
OBJECT head; // temporary head of list - because pObjList is not usually a OBJECT
|
||||
|
||||
// put at head of list
|
||||
head.pNext = pObjList->pNext;
|
||||
head.pNext = *pObjList;
|
||||
|
||||
// set head of list dummy OBJ Z Y values to lowest possible
|
||||
head.yPos = intToFrac(MIN_INT16);
|
||||
|
|
|
@ -134,15 +134,15 @@ void CopyObject( // copy one object to another
|
|||
OBJECT *pSrc); // source object
|
||||
|
||||
void InsertObject( // insert a object onto a sorted object list
|
||||
OBJECT *pObjList, // list to insert object onto
|
||||
OBJECT **pObjList, // list to insert object onto
|
||||
OBJECT *pInsObj); // object to insert
|
||||
|
||||
void DelObject( // delete a object from a object list and add to free list
|
||||
OBJECT *pObjList, // list to delete object from
|
||||
OBJECT **pObjList, // list to delete object from
|
||||
OBJECT *pDelObj); // object to delete
|
||||
|
||||
void SortObjectList( // re-sort an object list
|
||||
OBJECT *pObjList); // list to sort
|
||||
OBJECT **pObjList); // list to sort
|
||||
|
||||
OBJECT *GetNextObject( // object list iterator - returns next obj in list
|
||||
OBJECT *pObjList, // which object list
|
||||
|
|
|
@ -104,7 +104,7 @@ int JustifyText(char *szStr, int xPos, const FONT *pFont, int mode) {
|
|||
* @param mode Mode flags for the string
|
||||
* @param sleepTime Sleep time between each character (if non-zero)
|
||||
*/
|
||||
OBJECT *ObjectTextOut(OBJECT *pList, char *szStr, int color,
|
||||
OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
|
||||
int xPos, int yPos, SCNHANDLE hFont, int mode, int sleepTime) {
|
||||
int xJustify; // x position of text after justification
|
||||
int yOffset; // offset to next line of text
|
||||
|
|
|
@ -95,7 +95,7 @@ struct TEXTOUT {
|
|||
* @param mode mode flags for the string
|
||||
* @param sleepTime Sleep time between each character (if non-zero)
|
||||
*/
|
||||
OBJECT *ObjectTextOut(OBJECT *pList, char *szStr, int color,
|
||||
OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
|
||||
int xPos, int yPos, SCNHANDLE hFont, int mode, int sleepTime = 0);
|
||||
|
||||
OBJECT *ObjectTextOutIndirect( // output a string of text
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue