mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-11 11:45:21 +00:00
254 lines
7.1 KiB
C++
254 lines
7.1 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.
|
|
*
|
|
* 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;
|
|
|
|
/**
|
|
* Called to initialize 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 color
|
|
SetBgndColor(pBgnd->rgbSkyColor);
|
|
|
|
// 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 center of the specified playfield
|
|
* @param which Which playfield
|
|
*/
|
|
|
|
int PlayfieldGetCenterX(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 &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(&pPlay->pDispList);
|
|
|
|
// generate clipping rects for all objects that have moved etc.
|
|
FindMovingObjects(&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(&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();
|
|
}
|
|
|
|
} // End of namespace Tinsel
|