mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-19 08:25:35 +00:00
SCI: Break the huge kernelFrameOut function into several smaller ones
Also, prefix more class variables with underscores
This commit is contained in:
parent
10e14367ec
commit
b400e142af
@ -56,8 +56,8 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd
|
||||
: _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) {
|
||||
|
||||
_coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster;
|
||||
scriptsRunningWidth = 320;
|
||||
scriptsRunningHeight = 200;
|
||||
_scriptsRunningWidth = 320;
|
||||
_scriptsRunningHeight = 200;
|
||||
}
|
||||
|
||||
GfxFrameout::~GfxFrameout() {
|
||||
@ -80,11 +80,11 @@ void GfxFrameout::kernelAddPlane(reg_t object) {
|
||||
|
||||
// The above can be 0 in SCI3 (e.g. Phantasmagoria 2)
|
||||
if (tmpRunningWidth > 0 && tmpRunningHeight > 0) {
|
||||
scriptsRunningWidth = tmpRunningWidth;
|
||||
scriptsRunningHeight = tmpRunningHeight;
|
||||
_scriptsRunningWidth = tmpRunningWidth;
|
||||
_scriptsRunningHeight = tmpRunningHeight;
|
||||
}
|
||||
|
||||
_coordAdjuster->setScriptsResolution(scriptsRunningWidth, scriptsRunningHeight);
|
||||
_coordAdjuster->setScriptsResolution(_scriptsRunningWidth, _scriptsRunningHeight);
|
||||
}
|
||||
|
||||
newPlane.object = object;
|
||||
@ -122,10 +122,10 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
|
||||
it->planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right));
|
||||
|
||||
Common::Rect screenRect(_screen->getWidth(), _screen->getHeight());
|
||||
it->planeRect.top = (it->planeRect.top * screenRect.height()) / scriptsRunningHeight;
|
||||
it->planeRect.left = (it->planeRect.left * screenRect.width()) / scriptsRunningWidth;
|
||||
it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / scriptsRunningHeight;
|
||||
it->planeRect.right = (it->planeRect.right * screenRect.width()) / scriptsRunningWidth;
|
||||
it->planeRect.top = (it->planeRect.top * screenRect.height()) / _scriptsRunningHeight;
|
||||
it->planeRect.left = (it->planeRect.left * screenRect.width()) / _scriptsRunningWidth;
|
||||
it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / _scriptsRunningHeight;
|
||||
it->planeRect.right = (it->planeRect.right * screenRect.width()) / _scriptsRunningWidth;
|
||||
|
||||
// We get negative left in kq7 in scrolling rooms
|
||||
if (it->planeRect.left < 0) {
|
||||
@ -189,10 +189,10 @@ void GfxFrameout::kernelDeletePlane(reg_t object) {
|
||||
planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right));
|
||||
|
||||
Common::Rect screenRect(_screen->getWidth(), _screen->getHeight());
|
||||
planeRect.top = (planeRect.top * screenRect.height()) / scriptsRunningHeight;
|
||||
planeRect.left = (planeRect.left * screenRect.width()) / scriptsRunningWidth;
|
||||
planeRect.bottom = (planeRect.bottom * screenRect.height()) / scriptsRunningHeight;
|
||||
planeRect.right = (planeRect.right * screenRect.width()) / scriptsRunningWidth;
|
||||
planeRect.top = (planeRect.top * screenRect.height()) / _scriptsRunningHeight;
|
||||
planeRect.left = (planeRect.left * screenRect.width()) / _scriptsRunningWidth;
|
||||
planeRect.bottom = (planeRect.bottom * screenRect.height()) / _scriptsRunningHeight;
|
||||
planeRect.right = (planeRect.right * screenRect.width()) / _scriptsRunningWidth;
|
||||
planeRect.clip(screenRect); // we need to do this, at least in gk1 on cemetary we get bottom right -> 201, 321
|
||||
// FIXME: The code above incorrectly added 1 pixel to the plane's
|
||||
// bottom and right, so probably the plane clipping code is no
|
||||
@ -332,37 +332,149 @@ void GfxFrameout::sortPlanes() {
|
||||
Common::sort(_planes.begin(), _planes.end(), planeSortHelper);
|
||||
}
|
||||
|
||||
int16 GfxFrameout::upscaleHorizontalCoordinate(int16 coordinate) {
|
||||
return ((coordinate * _screen->getWidth()) / _scriptsRunningWidth);
|
||||
}
|
||||
|
||||
int16 GfxFrameout::upscaleVerticalCoordinate(int16 coordinate) {
|
||||
return ((coordinate * _screen->getHeight()) / _scriptsRunningHeight);
|
||||
}
|
||||
|
||||
Common::Rect GfxFrameout::upscaleRect(Common::Rect &rect) {
|
||||
rect.top = (rect.top * _scriptsRunningHeight) / _screen->getHeight();
|
||||
rect.left = (rect.left * _scriptsRunningWidth) / _screen->getWidth();
|
||||
rect.bottom = (rect.bottom * _scriptsRunningHeight) / _screen->getHeight();
|
||||
rect.right = (rect.right * _scriptsRunningWidth) / _screen->getWidth();
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void GfxFrameout::showVideo() {
|
||||
bool skipVideo = false;
|
||||
RobotDecoder *videoDecoder = g_sci->_robotDecoder;
|
||||
uint16 x = videoDecoder->getPos().x;
|
||||
uint16 y = videoDecoder->getPos().y;
|
||||
|
||||
if (videoDecoder->hasDirtyPalette())
|
||||
videoDecoder->setSystemPalette();
|
||||
|
||||
while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
|
||||
if (videoDecoder->needsUpdate()) {
|
||||
const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
|
||||
if (frame) {
|
||||
g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
|
||||
|
||||
if (videoDecoder->hasDirtyPalette())
|
||||
videoDecoder->setSystemPalette();
|
||||
|
||||
g_system->updateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
|
||||
skipVideo = true;
|
||||
}
|
||||
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
}
|
||||
|
||||
void GfxFrameout::createPlaneItemList(reg_t planeObject, FrameoutList &itemList) {
|
||||
// Copy screen items of the current frame to the list of items to be drawn
|
||||
for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) {
|
||||
reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane));
|
||||
if (planeObject == itemPlane) {
|
||||
kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary?
|
||||
itemList.push_back(*listIterator);
|
||||
}
|
||||
}
|
||||
|
||||
for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
|
||||
if (pictureIt->object == planeObject) {
|
||||
GfxPicture *planePicture = pictureIt->picture;
|
||||
// Allocate memory for picture cels
|
||||
pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()];
|
||||
|
||||
// Add following cels to the itemlist
|
||||
FrameoutEntry *picEntry = pictureIt->pictureCels;
|
||||
int planePictureCels = planePicture->getSci32celCount();
|
||||
for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) {
|
||||
picEntry->celNo = pictureCelNr;
|
||||
picEntry->object = NULL_REG;
|
||||
picEntry->picture = planePicture;
|
||||
picEntry->y = planePicture->getSci32celY(pictureCelNr);
|
||||
picEntry->x = planePicture->getSci32celX(pictureCelNr);
|
||||
picEntry->picStartX = pictureIt->startX;
|
||||
picEntry->picStartY = pictureIt->startY;
|
||||
|
||||
picEntry->priority = planePicture->getSci32celPriority(pictureCelNr);
|
||||
|
||||
itemList.push_back(picEntry);
|
||||
picEntry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now sort our itemlist
|
||||
Common::sort(itemList.begin(), itemList.end(), sortHelper);
|
||||
}
|
||||
|
||||
bool GfxFrameout::isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY) {
|
||||
// Out of view horizontally (sanity checks)
|
||||
int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x;
|
||||
int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo);
|
||||
int16 planeStartX = planeOffsetX;
|
||||
int16 planeEndX = planeStartX + planeRect.width();
|
||||
if (pictureCelEndX < planeStartX)
|
||||
return true;
|
||||
if (pictureCelStartX > planeEndX)
|
||||
return true;
|
||||
|
||||
// Out of view vertically (sanity checks)
|
||||
int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y;
|
||||
int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo);
|
||||
int16 planeStartY = planeOffsetY;
|
||||
int16 planeEndY = planeStartY + planeRect.height();
|
||||
if (pictureCelEndY < planeStartY)
|
||||
return true;
|
||||
if (pictureCelStartY > planeEndY)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GfxFrameout::drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored) {
|
||||
int16 pictureOffsetX = planeOffsetX;
|
||||
int16 pictureX = itemEntry->x;
|
||||
if ((planeOffsetX) || (itemEntry->picStartX)) {
|
||||
if (planeOffsetX <= itemEntry->picStartX) {
|
||||
pictureX += itemEntry->picStartX - planeOffsetX;
|
||||
pictureOffsetX = 0;
|
||||
} else {
|
||||
pictureOffsetX = planeOffsetX - itemEntry->picStartX;
|
||||
}
|
||||
}
|
||||
|
||||
int16 pictureOffsetY = planeOffsetY;
|
||||
int16 pictureY = itemEntry->y;
|
||||
if ((planeOffsetY) || (itemEntry->picStartY)) {
|
||||
if (planeOffsetY <= itemEntry->picStartY) {
|
||||
pictureY += itemEntry->picStartY - planeOffsetY;
|
||||
pictureOffsetY = 0;
|
||||
} else {
|
||||
pictureOffsetY = planeOffsetY - itemEntry->picStartY;
|
||||
}
|
||||
}
|
||||
|
||||
itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, planePictureMirrored);
|
||||
// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
|
||||
}
|
||||
|
||||
void GfxFrameout::kernelFrameout() {
|
||||
if (g_sci->_robotDecoder->isVideoLoaded()) {
|
||||
bool skipVideo = false;
|
||||
RobotDecoder *videoDecoder = g_sci->_robotDecoder;
|
||||
uint16 x = videoDecoder->getPos().x;
|
||||
uint16 y = videoDecoder->getPos().y;
|
||||
|
||||
if (videoDecoder->hasDirtyPalette())
|
||||
videoDecoder->setSystemPalette();
|
||||
|
||||
while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
|
||||
if (videoDecoder->needsUpdate()) {
|
||||
const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
|
||||
if (frame) {
|
||||
g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
|
||||
|
||||
if (videoDecoder->hasDirtyPalette())
|
||||
videoDecoder->setSystemPalette();
|
||||
|
||||
g_system->updateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
|
||||
skipVideo = true;
|
||||
}
|
||||
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
showVideo();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -396,43 +508,7 @@ void GfxFrameout::kernelFrameout() {
|
||||
|
||||
FrameoutList itemList;
|
||||
|
||||
// Copy screen items of the current frame to the list of items to be drawn
|
||||
for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) {
|
||||
reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane));
|
||||
if (planeObject == itemPlane) {
|
||||
kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary?
|
||||
itemList.push_back(*listIterator);
|
||||
}
|
||||
}
|
||||
|
||||
for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
|
||||
if (pictureIt->object == planeObject) {
|
||||
GfxPicture *planePicture = pictureIt->picture;
|
||||
// Allocate memory for picture cels
|
||||
pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()];
|
||||
|
||||
// Add following cels to the itemlist
|
||||
FrameoutEntry *picEntry = pictureIt->pictureCels;
|
||||
int planePictureCels = planePicture->getSci32celCount();
|
||||
for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) {
|
||||
picEntry->celNo = pictureCelNr;
|
||||
picEntry->object = NULL_REG;
|
||||
picEntry->picture = planePicture;
|
||||
picEntry->y = planePicture->getSci32celY(pictureCelNr);
|
||||
picEntry->x = planePicture->getSci32celX(pictureCelNr);
|
||||
picEntry->picStartX = pictureIt->startX;
|
||||
picEntry->picStartY = pictureIt->startY;
|
||||
|
||||
picEntry->priority = planePicture->getSci32celPriority(pictureCelNr);
|
||||
|
||||
itemList.push_back(picEntry);
|
||||
picEntry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now sort our itemlist
|
||||
Common::sort(itemList.begin(), itemList.end(), sortHelper);
|
||||
createPlaneItemList(planeObject, itemList);
|
||||
|
||||
// warning("Plane %s", _segMan->getObjectName(planeObject));
|
||||
|
||||
@ -441,56 +517,13 @@ void GfxFrameout::kernelFrameout() {
|
||||
|
||||
if (itemEntry->object.isNull()) {
|
||||
// Picture cel data
|
||||
itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight);
|
||||
itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth);
|
||||
itemEntry->picStartX = ((itemEntry->picStartX * _screen->getWidth()) / scriptsRunningWidth);
|
||||
itemEntry->picStartY = ((itemEntry->picStartY * _screen->getHeight()) / scriptsRunningHeight);
|
||||
|
||||
// Out of view horizontally (sanity checks)
|
||||
int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x;
|
||||
int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo);
|
||||
int16 planeStartX = it->planeOffsetX;
|
||||
int16 planeEndX = planeStartX + it->planeRect.width();
|
||||
if (pictureCelEndX < planeStartX)
|
||||
continue;
|
||||
if (pictureCelStartX > planeEndX)
|
||||
continue;
|
||||
|
||||
// Out of view vertically (sanity checks)
|
||||
int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y;
|
||||
int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo);
|
||||
int16 planeStartY = it->planeOffsetY;
|
||||
int16 planeEndY = planeStartY + it->planeRect.height();
|
||||
if (pictureCelEndY < planeStartY)
|
||||
continue;
|
||||
if (pictureCelStartY > planeEndY)
|
||||
continue;
|
||||
|
||||
int16 pictureOffsetX = it->planeOffsetX;
|
||||
int16 pictureX = itemEntry->x;
|
||||
if ((it->planeOffsetX) || (itemEntry->picStartX)) {
|
||||
if (it->planeOffsetX <= itemEntry->picStartX) {
|
||||
pictureX += itemEntry->picStartX - it->planeOffsetX;
|
||||
pictureOffsetX = 0;
|
||||
} else {
|
||||
pictureOffsetX = it->planeOffsetX - itemEntry->picStartX;
|
||||
}
|
||||
}
|
||||
|
||||
int16 pictureOffsetY = it->planeOffsetY;
|
||||
int16 pictureY = itemEntry->y;
|
||||
if ((it->planeOffsetY) || (itemEntry->picStartY)) {
|
||||
if (it->planeOffsetY <= itemEntry->picStartY) {
|
||||
pictureY += itemEntry->picStartY - it->planeOffsetY;
|
||||
pictureOffsetY = 0;
|
||||
} else {
|
||||
pictureOffsetY = it->planeOffsetY - itemEntry->picStartY;
|
||||
}
|
||||
}
|
||||
|
||||
itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, it->planePictureMirrored);
|
||||
// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
|
||||
itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x);
|
||||
itemEntry->y = upscaleVerticalCoordinate(itemEntry->y);
|
||||
itemEntry->picStartX = upscaleHorizontalCoordinate(itemEntry->picStartX);
|
||||
itemEntry->picStartY = upscaleVerticalCoordinate(itemEntry->picStartY);
|
||||
|
||||
if (!isPictureOutOfView(itemEntry, it->planeRect, it->planeOffsetX, it->planeOffsetY))
|
||||
drawPicture(itemEntry, it->planeOffsetX, it->planeOffsetY, it->planePictureMirrored);
|
||||
} else {
|
||||
GfxView *view = (itemEntry->viewId != 0xFFFF) ? _cache->getView(itemEntry->viewId) : NULL;
|
||||
|
||||
@ -499,9 +532,9 @@ void GfxFrameout::kernelFrameout() {
|
||||
view->adjustToUpscaledCoordinates(itemEntry->y, itemEntry->x);
|
||||
view->adjustToUpscaledCoordinates(itemEntry->z, dummyX);
|
||||
} else if (getSciVersion() == SCI_VERSION_2_1) {
|
||||
itemEntry->y = (itemEntry->y * _screen->getHeight()) / scriptsRunningHeight;
|
||||
itemEntry->x = (itemEntry->x * _screen->getWidth()) / scriptsRunningWidth;
|
||||
itemEntry->z = (itemEntry->z * _screen->getHeight()) / scriptsRunningHeight;
|
||||
itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x);
|
||||
itemEntry->y = upscaleVerticalCoordinate(itemEntry->y);
|
||||
itemEntry->z = upscaleVerticalCoordinate(itemEntry->z);
|
||||
}
|
||||
|
||||
// Adjust according to current scroll position
|
||||
@ -538,10 +571,7 @@ void GfxFrameout::kernelFrameout() {
|
||||
view->adjustBackUpscaledCoordinates(nsRect.top, nsRect.left);
|
||||
view->adjustBackUpscaledCoordinates(nsRect.bottom, nsRect.right);
|
||||
} else if (getSciVersion() == SCI_VERSION_2_1) {
|
||||
nsRect.top = (nsRect.top * scriptsRunningHeight) / _screen->getHeight();
|
||||
nsRect.left = (nsRect.left * scriptsRunningWidth) / _screen->getWidth();
|
||||
nsRect.bottom = (nsRect.bottom * scriptsRunningHeight) / _screen->getHeight();
|
||||
nsRect.right = (nsRect.right * scriptsRunningWidth) / _screen->getWidth();
|
||||
nsRect = upscaleRect(nsRect);
|
||||
}
|
||||
|
||||
if (g_sci->getGameId() == GID_PHANTASMAGORIA2) {
|
||||
|
@ -104,6 +104,14 @@ public:
|
||||
void clear();
|
||||
|
||||
private:
|
||||
void showVideo();
|
||||
void createPlaneItemList(reg_t planeObject, FrameoutList &itemList);
|
||||
bool isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY);
|
||||
void drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored);
|
||||
int16 upscaleHorizontalCoordinate(int16 coordinate);
|
||||
int16 upscaleVerticalCoordinate(int16 coordinate);
|
||||
Common::Rect upscaleRect(Common::Rect &rect);
|
||||
|
||||
SegManager *_segMan;
|
||||
ResourceManager *_resMan;
|
||||
GfxCoordAdjuster32 *_coordAdjuster;
|
||||
@ -118,8 +126,8 @@ private:
|
||||
|
||||
void sortPlanes();
|
||||
|
||||
uint16 scriptsRunningWidth;
|
||||
uint16 scriptsRunningHeight;
|
||||
uint16 _scriptsRunningWidth;
|
||||
uint16 _scriptsRunningHeight;
|
||||
};
|
||||
|
||||
} // End of namespace Sci
|
||||
|
Loading…
x
Reference in New Issue
Block a user