2017-05-26 05:24:38 +02:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2017-05-29 07:51:40 +02:00
|
|
|
#include "common/debug.h"
|
2017-06-05 19:10:47 +02:00
|
|
|
#include "common/rect.h"
|
2017-05-29 07:51:40 +02:00
|
|
|
#include "image/png.h"
|
|
|
|
#include "graphics/surface.h"
|
2017-06-16 18:01:58 +02:00
|
|
|
#include "graphics/transparent_surface.h"
|
2017-05-29 10:27:23 +02:00
|
|
|
#include "graphics/palette.h"
|
2017-06-05 19:10:47 +02:00
|
|
|
|
|
|
|
#include "sludge/allfiles.h"
|
|
|
|
#include "sludge/newfatal.h"
|
|
|
|
#include "sludge/fileset.h"
|
|
|
|
#include "sludge/backdrop.h"
|
|
|
|
#include "sludge/moreio.h"
|
2017-07-15 15:33:43 +02:00
|
|
|
#include "sludge/statusba.h"
|
|
|
|
#include "sludge/talk.h"
|
2017-06-05 19:10:47 +02:00
|
|
|
#include "sludge/zbuffer.h"
|
|
|
|
#include "sludge/sludge.h"
|
|
|
|
#include "sludge/sludger.h"
|
|
|
|
#include "sludge/variable.h"
|
|
|
|
#include "sludge/imgloader.h"
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-05-26 21:25:11 +02:00
|
|
|
namespace Sludge {
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-05-26 21:25:11 +02:00
|
|
|
extern inputType input;
|
2017-06-03 21:10:38 +02:00
|
|
|
extern Graphics::Surface renderSurface;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
|
|
|
bool freeze();
|
|
|
|
void unfreeze(bool); // Because FREEZE.H needs a load of other includes
|
|
|
|
|
2017-06-16 18:01:58 +02:00
|
|
|
bool backdropExists = false;
|
2017-07-01 22:01:26 +02:00
|
|
|
extern int zBufferToSet;
|
2017-06-16 18:01:58 +02:00
|
|
|
|
2017-06-16 15:49:14 +02:00
|
|
|
Graphics::Surface lightMap;
|
2017-07-15 16:20:16 +02:00
|
|
|
Graphics::Surface OrigBackdropSurface;
|
2017-05-29 07:51:40 +02:00
|
|
|
Graphics::Surface backdropSurface;
|
2017-07-15 15:33:43 +02:00
|
|
|
Graphics::Surface snapshotSurface;
|
2017-05-29 07:51:40 +02:00
|
|
|
|
2017-05-26 05:24:38 +02:00
|
|
|
float snapTexW = 1.0;
|
|
|
|
float snapTexH = 1.0;
|
|
|
|
|
2017-07-15 17:05:40 +02:00
|
|
|
uint winWidth, winHeight;
|
2017-05-26 05:24:38 +02:00
|
|
|
int lightMapMode = LIGHTMAPMODE_PIXEL;
|
|
|
|
parallaxLayer *parallaxStuff = NULL;
|
|
|
|
int cameraPX = 0, cameraPY = 0;
|
|
|
|
|
2017-07-10 21:44:14 +02:00
|
|
|
uint sceneWidth, sceneHeight;
|
2017-05-26 05:24:38 +02:00
|
|
|
int lightMapNumber;
|
2017-07-10 21:44:14 +02:00
|
|
|
uint currentBlankColour = TS_ARGB(255, 0, 0, 0);
|
2017-05-26 05:24:38 +02:00
|
|
|
|
|
|
|
extern int cameraX, cameraY;
|
|
|
|
extern float cameraZoom;
|
|
|
|
|
|
|
|
void nosnapshot() {
|
2017-07-15 15:33:43 +02:00
|
|
|
if (snapshotSurface.getPixels())
|
|
|
|
snapshotSurface.free();
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
2017-05-27 20:16:54 +02:00
|
|
|
void saveSnapshot(Common::WriteStream *stream) {
|
2017-07-15 15:33:43 +02:00
|
|
|
if (snapshotSurface.getPixels()) {
|
2017-05-30 09:59:56 +02:00
|
|
|
stream->writeByte(1); // 1 for snapshot follows
|
2017-07-15 15:33:43 +02:00
|
|
|
Image::writePNG(*stream, snapshotSurface);
|
2017-05-26 05:24:38 +02:00
|
|
|
} else {
|
2017-05-30 09:59:56 +02:00
|
|
|
stream->writeByte(0);
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
2017-05-27 20:16:54 +02:00
|
|
|
}
|
2017-05-26 05:24:38 +02:00
|
|
|
|
|
|
|
bool snapshot() {
|
|
|
|
nosnapshot();
|
2017-05-29 07:51:40 +02:00
|
|
|
if (!freeze())
|
|
|
|
return false;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 15:33:43 +02:00
|
|
|
// draw snapshot to backdrop
|
|
|
|
displayBase();
|
|
|
|
viewSpeech(); // ...and anything being said
|
2017-05-26 05:24:38 +02:00
|
|
|
drawStatusBar();
|
|
|
|
|
2017-07-15 15:33:43 +02:00
|
|
|
// copy backdrop to snapshot
|
|
|
|
snapshotSurface.copyFrom(backdropSurface);
|
|
|
|
|
2017-05-26 05:24:38 +02:00
|
|
|
unfreeze(false);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-27 20:16:54 +02:00
|
|
|
bool restoreSnapshot(Common::SeekableReadStream *stream) {
|
2017-07-15 15:33:43 +02:00
|
|
|
if (!(ImgLoader::loadImage(stream, &snapshotSurface))) {
|
2017-05-26 05:24:38 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void killBackDrop() {
|
2017-05-31 01:11:28 +02:00
|
|
|
if (backdropSurface.getPixels())
|
|
|
|
backdropSurface.free();
|
2017-06-16 18:01:58 +02:00
|
|
|
backdropExists = false;
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void killLightMap() {
|
2017-06-16 15:49:14 +02:00
|
|
|
if (lightMap.getPixels()) {
|
|
|
|
lightMap.free();
|
2017-05-31 01:11:28 +02:00
|
|
|
}
|
|
|
|
lightMapNumber = 0;
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void killParallax() {
|
|
|
|
while (parallaxStuff) {
|
|
|
|
parallaxLayer *k = parallaxStuff;
|
2017-05-28 09:48:25 +02:00
|
|
|
parallaxStuff = k->next;
|
2017-05-31 01:11:28 +02:00
|
|
|
k->surface.free();
|
2017-05-26 05:24:38 +02:00
|
|
|
delete k;
|
|
|
|
k = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool reserveBackdrop() {
|
|
|
|
cameraX = 0;
|
|
|
|
cameraY = 0;
|
2017-06-05 11:49:19 +02:00
|
|
|
input.mouseX = (int)((float)input.mouseX * cameraZoom);
|
|
|
|
input.mouseY = (int)((float)input.mouseY * cameraZoom);
|
2017-05-26 05:24:38 +02:00
|
|
|
cameraZoom = 1.0;
|
2017-06-05 11:49:19 +02:00
|
|
|
input.mouseX = (int)((float)input.mouseX / cameraZoom);
|
|
|
|
input.mouseY = (int)((float)input.mouseY / cameraZoom);
|
2017-05-26 05:24:38 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-31 01:11:28 +02:00
|
|
|
void killAllBackDrop() {
|
2017-05-26 05:24:38 +02:00
|
|
|
killLightMap();
|
|
|
|
killBackDrop();
|
|
|
|
killParallax();
|
|
|
|
killZBuffer();
|
2017-05-31 01:11:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool resizeBackdrop(int x, int y) {
|
2017-05-26 05:24:38 +02:00
|
|
|
sceneWidth = x;
|
|
|
|
sceneHeight = y;
|
|
|
|
return reserveBackdrop();
|
|
|
|
}
|
|
|
|
|
2017-05-31 01:11:28 +02:00
|
|
|
bool killResizeBackdrop(int x, int y) {
|
|
|
|
killAllBackDrop();
|
|
|
|
return resizeBackdrop(x, y);
|
|
|
|
}
|
|
|
|
|
2017-05-26 05:24:38 +02:00
|
|
|
void loadBackDrop(int fileNum, int x, int y) {
|
2017-05-29 07:51:40 +02:00
|
|
|
debug(kSludgeDebugGraphics, "Load back drop");
|
2017-05-26 05:24:38 +02:00
|
|
|
setResourceForFatal(fileNum);
|
2017-05-28 09:48:25 +02:00
|
|
|
if (!openFileFromNum(fileNum)) {
|
2017-05-26 05:24:38 +02:00
|
|
|
fatal("Can't load overlay image");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-28 09:48:25 +02:00
|
|
|
if (!loadHSI(bigDataFile, x, y, false)) {
|
2017-07-15 14:18:17 +02:00
|
|
|
Common::String mess = Common::String::format("Can't paste overlay image outside scene dimensions\n\nX = %i\nY = %i\nWidth = %i\nHeight = %i", x, y, sceneWidth, sceneHeight);
|
2017-05-26 05:24:38 +02:00
|
|
|
fatal(mess);
|
|
|
|
}
|
|
|
|
|
|
|
|
finishAccess();
|
|
|
|
setResourceForFatal(-1);
|
2017-07-01 22:01:26 +02:00
|
|
|
|
|
|
|
// set zBuffer if it's not set
|
|
|
|
if (zBufferToSet >= 0) {
|
|
|
|
setZBuffer(zBufferToSet);
|
|
|
|
zBufferToSet = -1;
|
|
|
|
}
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void mixBackDrop(int fileNum, int x, int y) {
|
|
|
|
setResourceForFatal(fileNum);
|
2017-05-28 09:48:25 +02:00
|
|
|
if (!openFileFromNum(fileNum)) {
|
2017-05-26 05:24:38 +02:00
|
|
|
fatal("Can't load overlay image");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-28 09:48:25 +02:00
|
|
|
if (!mixHSI(bigDataFile, x, y)) {
|
2017-05-26 05:24:38 +02:00
|
|
|
fatal("Can't paste overlay image outside screen dimensions");
|
|
|
|
}
|
|
|
|
|
|
|
|
finishAccess();
|
|
|
|
setResourceForFatal(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void blankScreen(int x1, int y1, int x2, int y2) {
|
2017-07-04 23:59:02 +02:00
|
|
|
// in case of no backdrop added at all
|
|
|
|
if (!backdropSurface.getPixels()) {
|
|
|
|
return;
|
|
|
|
}
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-05-29 07:51:40 +02:00
|
|
|
if (y1 < 0)
|
|
|
|
y1 = 0;
|
|
|
|
if (x1 < 0)
|
|
|
|
x1 = 0;
|
2017-06-05 11:49:19 +02:00
|
|
|
if (x2 > (int)sceneWidth)
|
|
|
|
x2 = (int)sceneWidth;
|
|
|
|
if (y2 > (int)sceneHeight)
|
|
|
|
y2 = (int)sceneHeight;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-04 23:59:02 +02:00
|
|
|
backdropSurface.fillRect(Common::Rect(x1, y1, x2, y2), currentBlankColour);
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
2017-07-15 16:20:16 +02:00
|
|
|
// This function is very useful for scrolling credits, but very little else
|
2017-05-26 05:24:38 +02:00
|
|
|
void hardScroll(int distance) {
|
2017-07-15 16:20:16 +02:00
|
|
|
// scroll 0 distance, return
|
2017-05-29 07:51:40 +02:00
|
|
|
if (!distance)
|
|
|
|
return;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 16:20:16 +02:00
|
|
|
// blank screen
|
|
|
|
blankScreen(0, 0, sceneWidth, sceneHeight);
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 16:20:16 +02:00
|
|
|
// scroll more than backdrop height, screen stay blank
|
|
|
|
if (ABS(distance) >= (int)sceneHeight) {
|
|
|
|
return;
|
|
|
|
}
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 16:20:16 +02:00
|
|
|
// copy part of the backdrop to it
|
|
|
|
if (distance > 0) {
|
|
|
|
backdropSurface.copyRectToSurface(OrigBackdropSurface, 0, 0,
|
|
|
|
Common::Rect(0, distance, backdropSurface.w, backdropSurface.h));
|
|
|
|
} else {
|
|
|
|
backdropSurface.copyRectToSurface(OrigBackdropSurface, 0, -distance,
|
|
|
|
Common::Rect(0, 0, backdropSurface.w, backdropSurface.h + distance));
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-10 21:44:14 +02:00
|
|
|
void drawVerticalLine(uint x, uint y1, uint y2) {
|
2017-07-11 11:09:26 +02:00
|
|
|
backdropSurface.drawLine(x, y1, x, y2, backdropSurface.format.ARGBToColor(255, 0, 0, 0));
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
2017-07-10 21:44:14 +02:00
|
|
|
void drawHorizontalLine(uint x1, uint y, uint x2) {
|
2017-07-11 11:09:26 +02:00
|
|
|
backdropSurface.drawLine(x1, y, x2, y, backdropSurface.format.ARGBToColor(255, 0, 0, 0));
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void darkScreen() {
|
2017-06-18 08:34:07 +02:00
|
|
|
Graphics::TransparentSurface tmp(backdropSurface, false);
|
|
|
|
tmp.blit(backdropSurface, 0, 0, Graphics::FLIP_NONE, nullptr, TS_ARGB(0, 255 >> 1, 0, 0));
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
inline int sortOutPCamera(int cX, int fX, int sceneMax, int boxMax) {
|
2017-06-05 11:49:19 +02:00
|
|
|
return (fX == 65535) ? (sceneMax ? ((cX * boxMax) / sceneMax) : 0) : ((cX * fX) / 100);
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void drawBackDrop() {
|
2017-07-04 23:59:02 +02:00
|
|
|
if (!backdropExists)
|
|
|
|
return;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 15:58:28 +02:00
|
|
|
// TODO: apply lightmap shader
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 15:58:28 +02:00
|
|
|
// draw parallaxStuff
|
2017-05-26 05:24:38 +02:00
|
|
|
if (parallaxStuff) {
|
2017-07-15 15:58:28 +02:00
|
|
|
// TODO: simulate image repeating effect
|
|
|
|
warning("Drawing parallaxStuff");
|
|
|
|
#if 0
|
2017-05-26 05:24:38 +02:00
|
|
|
parallaxLayer *ps = parallaxStuff;
|
|
|
|
|
2017-07-15 15:58:28 +02:00
|
|
|
// go to the parallax at bottom
|
2017-05-26 05:24:38 +02:00
|
|
|
while (ps->next) ps = ps->next;
|
|
|
|
|
2017-07-15 15:58:28 +02:00
|
|
|
// draw parallax one by one
|
2017-05-26 05:24:38 +02:00
|
|
|
while (ps) {
|
2017-07-15 15:58:28 +02:00
|
|
|
ps->cameraX = sortOutPCamera(cameraX, ps->fractionX, (int)(sceneWidth - (float)winWidth / cameraZoom), (int)(ps->surface.w - (float)winWidth / cameraZoom));
|
|
|
|
ps->cameraY = sortOutPCamera(cameraY, ps->fractionY, (int)(sceneHeight - (float)winHeight / cameraZoom), (int)(ps->surface.h - (float)winHeight / cameraZoom));
|
|
|
|
|
|
|
|
uint w = (ps->wrapS) ? sceneWidth : ps->surface.w;
|
|
|
|
uint h = (ps->wrapT) ? sceneHeight : ps->surface.h;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
|
|
|
const GLfloat vertices[] = {
|
2017-05-28 09:48:25 +02:00
|
|
|
(GLfloat) - ps->cameraX, (GLfloat) - ps->cameraY, 0.1f,
|
|
|
|
w - ps->cameraX, (GLfloat) - ps->cameraY, 0.1f,
|
|
|
|
(GLfloat) - ps->cameraX, h - ps->cameraY, 0.1f,
|
|
|
|
w - ps->cameraX, h - ps->cameraY, 0.1f
|
2017-05-26 05:24:38 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const GLfloat texCoords[] = {
|
|
|
|
0.0f, 0.0f,
|
|
|
|
texw, 0.0f,
|
|
|
|
0.0f, texh,
|
|
|
|
texw, texh
|
|
|
|
};
|
|
|
|
drawQuad(shader.smartScaler, vertices, 1, texCoords);
|
|
|
|
|
2017-05-28 09:48:25 +02:00
|
|
|
ps = ps->prev;
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
2017-07-15 15:58:28 +02:00
|
|
|
#endif
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
2017-07-15 15:58:28 +02:00
|
|
|
// draw backdrop
|
|
|
|
Graphics::TransparentSurface tmp(backdropSurface, false);
|
|
|
|
tmp.blit(renderSurface, 0, 0);
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool loadLightMap(int v) {
|
|
|
|
setResourceForFatal(v);
|
2017-06-05 11:49:19 +02:00
|
|
|
if (!openFileFromNum(v))
|
|
|
|
return fatal("Can't open light map.");
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-05-31 01:11:28 +02:00
|
|
|
killLightMap();
|
|
|
|
lightMapNumber = v;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-06-16 15:49:14 +02:00
|
|
|
if (!ImgLoader::loadImage(bigDataFile, &lightMap))
|
2017-05-31 01:11:28 +02:00
|
|
|
return false;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
|
|
|
if (lightMapMode == LIGHTMAPMODE_HOTSPOT) {
|
2017-06-16 15:49:14 +02:00
|
|
|
if (lightMap.w != sceneWidth || lightMap.h != sceneHeight) {
|
2017-05-26 05:24:38 +02:00
|
|
|
return fatal("Light map width and height don't match scene width and height. That is required for lightmaps in HOTSPOT mode.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
finishAccess();
|
|
|
|
|
|
|
|
setResourceForFatal(-1);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-07-10 21:44:14 +02:00
|
|
|
bool loadParallax(uint16 v, uint16 fracX, uint16 fracY) {
|
2017-05-26 05:24:38 +02:00
|
|
|
setResourceForFatal(v);
|
2017-06-05 11:49:19 +02:00
|
|
|
if (!openFileFromNum(v))
|
|
|
|
return fatal("Can't open parallax image");
|
2017-05-26 05:24:38 +02:00
|
|
|
|
|
|
|
parallaxLayer *nP = new parallaxLayer;
|
2017-06-05 11:49:19 +02:00
|
|
|
if (!checkNew(nP))
|
|
|
|
return false;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-05-28 09:48:25 +02:00
|
|
|
nP->next = parallaxStuff;
|
2017-05-26 05:24:38 +02:00
|
|
|
parallaxStuff = nP;
|
2017-05-28 09:48:25 +02:00
|
|
|
if (nP->next) {
|
|
|
|
nP->next->prev = nP;
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
2017-05-28 09:48:25 +02:00
|
|
|
nP->prev = NULL;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-06-01 00:50:06 +02:00
|
|
|
if (!ImgLoader::loadImage(bigDataFile, &nP->surface, 0))
|
2017-05-31 01:11:28 +02:00
|
|
|
return false;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-05-28 09:48:25 +02:00
|
|
|
nP->fileNum = v;
|
|
|
|
nP->fractionX = fracX;
|
|
|
|
nP->fractionY = fracY;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 15:58:28 +02:00
|
|
|
// 65535 is the value of AUTOFIT constant in Sludge
|
2017-05-26 05:24:38 +02:00
|
|
|
if (fracX == 65535) {
|
2017-05-28 09:48:25 +02:00
|
|
|
nP->wrapS = false;
|
2017-06-16 18:00:23 +02:00
|
|
|
if (nP->surface.w < winWidth) {
|
2017-05-26 05:24:38 +02:00
|
|
|
fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
2017-05-28 09:48:25 +02:00
|
|
|
nP->wrapS = true;
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fracY == 65535) {
|
2017-05-28 09:48:25 +02:00
|
|
|
nP->wrapT = false;
|
2017-06-16 18:00:23 +02:00
|
|
|
if (nP->surface.h < winHeight) {
|
2017-05-26 05:24:38 +02:00
|
|
|
fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
2017-05-28 09:48:25 +02:00
|
|
|
nP->wrapT = true;
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
2017-07-15 15:58:28 +02:00
|
|
|
// TODO: reinterpret this part
|
|
|
|
#if 0
|
2017-05-28 09:48:25 +02:00
|
|
|
if (nP->wrapS)
|
2017-07-15 15:58:28 +02:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
2017-05-26 05:24:38 +02:00
|
|
|
else
|
2017-07-15 15:58:28 +02:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
2017-05-28 09:48:25 +02:00
|
|
|
if (nP->wrapT)
|
2017-07-15 15:58:28 +02:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
2017-05-26 05:24:38 +02:00
|
|
|
else
|
2017-07-15 15:58:28 +02:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
2017-05-26 05:24:38 +02:00
|
|
|
#endif
|
2017-07-15 15:58:28 +02:00
|
|
|
|
2017-05-31 01:11:28 +02:00
|
|
|
finishAccess();
|
2017-05-26 05:24:38 +02:00
|
|
|
setResourceForFatal(-1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-28 10:41:01 +02:00
|
|
|
bool loadHSI(Common::SeekableReadStream *stream, int x, int y, bool reserve) {
|
2017-05-29 07:51:40 +02:00
|
|
|
debug(kSludgeDebugGraphics, "Load HSI");
|
2017-05-31 01:11:28 +02:00
|
|
|
if (reserve) {
|
|
|
|
killAllBackDrop(); // kill all
|
|
|
|
}
|
2017-05-28 10:41:01 +02:00
|
|
|
|
2017-06-01 00:50:06 +02:00
|
|
|
if (!ImgLoader::loadImage(stream, &backdropSurface, (int)reserve))
|
2017-05-28 10:41:01 +02:00
|
|
|
return false;
|
2017-05-31 01:11:28 +02:00
|
|
|
|
2017-07-13 23:26:47 +02:00
|
|
|
uint realPicWidth = backdropSurface.w;
|
|
|
|
uint realPicHeight = backdropSurface.h;
|
2017-05-31 01:11:28 +02:00
|
|
|
|
2017-07-15 17:33:10 +02:00
|
|
|
// resize backdrop
|
|
|
|
if (reserve) {
|
2017-06-05 11:49:19 +02:00
|
|
|
if (!resizeBackdrop(realPicWidth, realPicHeight))
|
|
|
|
return false;
|
2017-05-31 01:11:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (x == IN_THE_CENTRE)
|
|
|
|
x = (sceneWidth - realPicWidth) >> 1;
|
|
|
|
if (y == IN_THE_CENTRE)
|
|
|
|
y = (sceneHeight - realPicHeight) >> 1;
|
2017-06-05 11:49:19 +02:00
|
|
|
if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight) {
|
2017-05-31 01:11:28 +02:00
|
|
|
debug(kSludgeDebugGraphics, "Illegal back drop size");
|
|
|
|
return false;
|
|
|
|
}
|
2017-05-28 10:41:01 +02:00
|
|
|
|
2017-07-15 16:20:16 +02:00
|
|
|
OrigBackdropSurface.copyFrom(backdropSurface);
|
2017-06-16 18:01:58 +02:00
|
|
|
backdropExists = true;
|
2017-07-01 22:01:26 +02:00
|
|
|
|
2017-05-26 05:24:38 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-27 20:16:54 +02:00
|
|
|
bool mixHSI(Common::SeekableReadStream *stream, int x, int y) {
|
2017-05-31 01:11:28 +02:00
|
|
|
debug(kSludgeDebugGraphics, "Load mixHSI");
|
2017-06-16 18:01:58 +02:00
|
|
|
Graphics::Surface mixSurface;
|
|
|
|
if (!ImgLoader::loadImage(stream, &mixSurface, 0))
|
2017-05-31 01:11:28 +02:00
|
|
|
return false;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-13 23:26:47 +02:00
|
|
|
uint realPicWidth = mixSurface.w;
|
|
|
|
uint realPicHeight = mixSurface.h;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-06-05 11:49:19 +02:00
|
|
|
if (x == IN_THE_CENTRE)
|
|
|
|
x = (sceneWidth - realPicWidth) >> 1;
|
|
|
|
if (y == IN_THE_CENTRE)
|
|
|
|
y = (sceneHeight - realPicHeight) >> 1;
|
|
|
|
if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight)
|
|
|
|
return false;
|
2017-06-16 18:01:58 +02:00
|
|
|
|
|
|
|
Graphics::TransparentSurface tmp(mixSurface, false);
|
2017-06-16 18:29:11 +02:00
|
|
|
tmp.blit(backdropSurface, x, y, Graphics::FLIP_NONE, nullptr, TS_ARGB(255, 255 >> 1, 255, 255));
|
2017-06-16 18:01:58 +02:00
|
|
|
mixSurface.free();
|
2017-05-27 20:16:54 +02:00
|
|
|
|
2017-05-26 05:24:38 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-28 09:48:25 +02:00
|
|
|
void saveHSI(Common::WriteStream *stream) {
|
2017-07-05 19:20:50 +02:00
|
|
|
Image::writePNG(*stream, backdropSurface);
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
2017-05-28 09:48:25 +02:00
|
|
|
void saveParallaxRecursive(parallaxLayer *me, Common::WriteStream *stream) {
|
2017-05-26 05:24:38 +02:00
|
|
|
if (me) {
|
2017-05-28 09:48:25 +02:00
|
|
|
saveParallaxRecursive(me->next, stream);
|
2017-05-30 09:59:56 +02:00
|
|
|
stream->writeByte(1);
|
|
|
|
stream->writeUint16BE(me->fileNum);
|
|
|
|
stream->writeUint16BE(me->fractionX);
|
|
|
|
stream->writeUint16BE(me->fractionY);
|
2017-05-26 05:24:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-10 21:44:14 +02:00
|
|
|
bool getRGBIntoStack(uint x, uint y, stackHandler *sH) {
|
2017-05-26 05:24:38 +02:00
|
|
|
if (x >= sceneWidth || y >= sceneHeight) {
|
|
|
|
return fatal("Co-ordinates are outside current scene!");
|
|
|
|
}
|
|
|
|
|
|
|
|
variable newValue;
|
|
|
|
|
|
|
|
newValue.varType = SVT_NULL;
|
|
|
|
|
2017-07-15 16:28:19 +02:00
|
|
|
byte *target = (byte *)renderSurface.getBasePtr(x, y);
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 16:28:19 +02:00
|
|
|
setVariable(newValue, SVT_INT, target[1]);
|
2017-05-28 09:48:25 +02:00
|
|
|
if (!addVarToStackQuick(newValue, sH->first)) return false;
|
|
|
|
sH->last = sH->first;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 16:28:19 +02:00
|
|
|
setVariable(newValue, SVT_INT, target[2]);
|
2017-05-28 09:48:25 +02:00
|
|
|
if (!addVarToStackQuick(newValue, sH->first)) return false;
|
2017-05-26 05:24:38 +02:00
|
|
|
|
2017-07-15 16:28:19 +02:00
|
|
|
setVariable(newValue, SVT_INT, target[3]);
|
2017-05-28 09:48:25 +02:00
|
|
|
if (!addVarToStackQuick(newValue, sH->first)) return false;
|
2017-07-15 16:28:19 +02:00
|
|
|
|
2017-05-26 05:24:38 +02:00
|
|
|
return true;
|
|
|
|
}
|
2017-05-26 21:25:11 +02:00
|
|
|
|
|
|
|
} // End of namespace Sludge
|