scummvm/engines/tinsel/background.cpp
Max Horn 1dbf8d73d5 TINSEL: Mark all (?) global vars with a FIXME comment
Use of global vars is what prevents RTL from working in Tinsel (and
probably in other engines). More specifically, the fact that many
global vars are not explicitly inited when the engine is (re)launched.

svn-id: r54262
2010-11-16 09:53:55 +00:00

266 lines
7.3 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
* Background handling code.
*/
#include "tinsel/background.h"
#include "tinsel/cliprect.h" // object clip rect defs
#include "tinsel/graphics.h"
#include "tinsel/sched.h" // process sheduler defs
#include "tinsel/object.h"
#include "tinsel/pid.h" // process identifiers
#include "tinsel/tinsel.h"
namespace Tinsel {
// FIXME: Avoid non-const global vars
// current background
const BACKGND *pCurBgnd = NULL;
// FIXME: Not yet used
static bool bEntireRedraw;
/**
* Called to initialise a background.
* @param pBgnd Pointer to data struct for current background
*/
void InitBackground(const BACKGND *pBgnd) {
int i; // playfield counter
PLAYFIELD *pPlayfield; // pointer to current playfield
// set current background
pCurBgnd = pBgnd;
// init background sky colour
SetBgndColour(pBgnd->rgbSkyColour);
// start of playfield array
pPlayfield = pBgnd->fieldArray;
// for each background playfield
for (i = 0; i < pBgnd->numPlayfields; i++, pPlayfield++) {
// init playfield pos
pPlayfield->fieldX = intToFrac(pBgnd->ptInitWorld.x);
pPlayfield->fieldY = intToFrac(pBgnd->ptInitWorld.y);
// no scrolling
pPlayfield->fieldXvel = intToFrac(0);
pPlayfield->fieldYvel = intToFrac(0);
// clear playfield display list
pPlayfield->pDispList = NULL;
// clear playfield moved flag
pPlayfield->bMoved = false;
}
}
/**
* Sets the xy position of the specified playfield in the current background.
* @param which Which playfield
* @param newXpos New x position
* @param newYpos New y position
*/
void PlayfieldSetPos(int which, int newXpos, int newYpos) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
assert(pCurBgnd != NULL);
// make sure the playfield number is in range
assert(which >= 0 && which < pCurBgnd->numPlayfields);
// get playfield pointer
pPlayfield = pCurBgnd->fieldArray + which;
// set new integer position
pPlayfield->fieldX = intToFrac(newXpos);
pPlayfield->fieldY = intToFrac(newYpos);
// set moved flag
pPlayfield->bMoved = true;
}
/**
* Returns the xy position of the specified playfield in the current background.
* @param which Which playfield
* @param pXpos Returns current x position
* @param pYpos Returns current y position
*/
void PlayfieldGetPos(int which, int *pXpos, int *pYpos) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
assert(pCurBgnd != NULL);
// make sure the playfield number is in range
assert(which >= 0 && which < pCurBgnd->numPlayfields);
// get playfield pointer
pPlayfield = pCurBgnd->fieldArray + which;
// get current integer position
*pXpos = fracToInt(pPlayfield->fieldX);
*pYpos = fracToInt(pPlayfield->fieldY);
}
/**
* Returns the x position of the centre of the specified playfield
* @param which Which playfield
*/
int PlayfieldGetCentreX(int which) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
assert(pCurBgnd != NULL);
// make sure the playfield number is in range
assert(which >= 0 && which < pCurBgnd->numPlayfields);
// get playfield pointer
pPlayfield = pCurBgnd->fieldArray + which;
// get current integer position
return fracToInt(pPlayfield->fieldX) + SCREEN_WIDTH/2;
}
/**
* Returns the display list for the specified playfield.
* @param which Which playfield
*/
OBJECT *GetPlayfieldList(int which) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
assert(pCurBgnd != NULL);
// make sure the playfield number is in range
assert(which >= 0 && which < pCurBgnd->numPlayfields);
// get playfield pointer
pPlayfield = pCurBgnd->fieldArray + which;
// return the display list pointer for this playfield
return (OBJECT *)&pPlayfield->pDispList;
}
/**
* Draws all the playfield object lists for the current background.
* The playfield velocity is added to the playfield position in order
* to scroll each playfield before it is drawn.
*/
void DrawBackgnd() {
int i; // playfield counter
PLAYFIELD *pPlay; // playfield pointer
int prevX, prevY; // save interger part of position
Common::Point ptWin; // window top left
if (pCurBgnd == NULL)
return; // no current background
// scroll each background playfield
for (i = 0; i < pCurBgnd->numPlayfields; i++) {
// get pointer to correct playfield
pPlay = pCurBgnd->fieldArray + i;
// save integer part of position
prevX = fracToInt(pPlay->fieldX);
prevY = fracToInt(pPlay->fieldY);
// update scrolling
pPlay->fieldX += pPlay->fieldXvel;
pPlay->fieldY += pPlay->fieldYvel;
// convert fixed point window pos to a int
ptWin.x = fracToInt(pPlay->fieldX);
ptWin.y = fracToInt(pPlay->fieldY);
// set the moved flag if the playfield has moved
if (prevX != ptWin.x || prevY != ptWin.y)
pPlay->bMoved = true;
// sort the display list for this background - just in case somebody has changed object Z positions
SortObjectList((OBJECT *)&pPlay->pDispList);
// generate clipping rects for all objects that have moved etc.
FindMovingObjects((OBJECT *)&pPlay->pDispList, &ptWin,
&pPlay->rcClip, false, pPlay->bMoved);
// clear playfield moved flag
pPlay->bMoved = false;
}
// merge the clipping rectangles
MergeClipRect();
// redraw all playfields within the clipping rectangles
const RectList &clipRects = GetClipRects();
for (RectList::const_iterator r = clipRects.begin(); r != clipRects.end(); ++r) {
// clear the clip rectangle on the virtual screen
// for each background playfield
for (i = 0; i < pCurBgnd->numPlayfields; i++) {
Common::Rect rcPlayClip; // clip rect for this playfield
// get pointer to correct playfield
pPlay = pCurBgnd->fieldArray + i;
// convert fixed point window pos to a int
ptWin.x = fracToInt(pPlay->fieldX);
ptWin.y = fracToInt(pPlay->fieldY);
if (IntersectRectangle(rcPlayClip, pPlay->rcClip, *r))
// redraw all objects within this clipping rect
UpdateClipRect((OBJECT *)&pPlay->pDispList,
&ptWin, &rcPlayClip);
}
}
// transfer any new palettes to the video DAC
PalettesToVideoDAC();
// update the screen within the clipping rectangles
for (RectList::const_iterator r = clipRects.begin(); r != clipRects.end(); ++r) {
UpdateScreenRect(*r);
}
g_system->updateScreen();
// delete all the clipping rectangles
ResetClipRect();
}
void ForceEntireRedraw() {
bEntireRedraw = true;
}
} // End of namespace Tinsel