mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-01 06:58:34 +00:00
1dbf8d73d5
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
266 lines
7.3 KiB
C++
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
|