From 0e7d9b4eb2c647843a24e090ff71678beb07716f Mon Sep 17 00:00:00 2001 From: Simei Yin Date: Wed, 19 Jul 2017 13:37:54 +0200 Subject: SLUDGE: Objectify parallex and create graphics manager --- engines/sludge/backdrop.cpp | 237 ++++++++++++++++++++++---------------------- engines/sludge/backdrop.h | 38 +++---- engines/sludge/builtin.cpp | 5 +- engines/sludge/freeze.cpp | 10 +- engines/sludge/freeze.h | 2 +- engines/sludge/graphics.cpp | 61 ++++++++++++ engines/sludge/graphics.h | 46 +++++++++ engines/sludge/loadsave.cpp | 6 +- engines/sludge/module.mk | 1 + engines/sludge/sludge.cpp | 4 + engines/sludge/sludge.h | 2 + 11 files changed, 264 insertions(+), 148 deletions(-) create mode 100644 engines/sludge/graphics.cpp create mode 100644 engines/sludge/graphics.h (limited to 'engines') diff --git a/engines/sludge/backdrop.cpp b/engines/sludge/backdrop.cpp index 0f94f56fee..6fc4bc7780 100644 --- a/engines/sludge/backdrop.cpp +++ b/engines/sludge/backdrop.cpp @@ -30,6 +30,7 @@ #include "sludge/allfiles.h" #include "sludge/newfatal.h" #include "sludge/fileset.h" +#include "sludge/graphics.h" #include "sludge/backdrop.h" #include "sludge/moreio.h" #include "sludge/statusba.h" @@ -61,7 +62,6 @@ float snapTexH = 1.0; uint winWidth, winHeight; int lightMapMode = LIGHTMAPMODE_PIXEL; -parallaxLayer *parallaxStuff = NULL; int cameraPX = 0, cameraPY = 0; uint sceneWidth, sceneHeight; @@ -71,6 +71,121 @@ uint currentBlankColour = TS_ARGB(255, 0, 0, 0); extern int cameraX, cameraY; extern float cameraZoom; +Parallax::~Parallax() { + kill(); +} + +void Parallax::kill() { + ParallaxLayers::iterator it; + for (it = _parallaxLayers.begin(); it != _parallaxLayers.end(); ++it) { + (*it)->surface.free(); + delete (*it); + (*it) = nullptr; + } + _parallaxLayers.clear(); +} + +bool Parallax::add(uint16 v, uint16 fracX, uint16 fracY) { + setResourceForFatal(v); + if (!g_sludge->_resMan->openFileFromNum(v)) + return fatal("Can't open parallax image"); + + ParallaxLayer *nP = new ParallaxLayer; + if (!checkNew(nP)) + return false; + + _parallaxLayers.push_back(nP); + + if (!ImgLoader::loadImage(g_sludge->_resMan->getData(), &nP->surface, 0)) + return false; + + nP->fileNum = v; + nP->fractionX = fracX; + nP->fractionY = fracY; + + // 65535 is the value of AUTOFIT constant in Sludge + if (fracX == 65535) { + nP->wrapS = false; + if (nP->surface.w < winWidth) { + fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen."); + return false; + } + } else { + nP->wrapS = true; + } + + if (fracY == 65535) { + nP->wrapT = false; + if (nP->surface.h < winHeight) { + fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen."); + return false; + } + } else { + nP->wrapT = true; + } + + // TODO: reinterpret this part +#if 0 + if (nP->wrapS) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + if (nP->wrapT) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#endif + + g_sludge->_resMan->finishAccess(); + setResourceForFatal(-1); + return true; +} + +void Parallax::draw() { + // draw parallaxStuff + if (!_parallaxLayers.empty()) { + // TODO: simulate image repeating effect + warning("Drawing parallaxStuff"); +#if 0 + // display parallax from bottom to top + ParallaxLayers::iterator it; + for (it = _parallax.begin(); it != _parallax.end(); ++it) { + (*it)->cameraX = sortOutPCamera(cameraX, (*it)->fractionX, (int)(sceneWidth - (float)winWidth / cameraZoom), (int)((*it)->surface.w - (float)winWidth / cameraZoom)); + (*it)->cameraY = sortOutPCamera(cameraY, (*it)->fractionY, (int)(sceneHeight - (float)winHeight / cameraZoom), (int)((*it)->surface.h - (float)winHeight / cameraZoom)); + + uint w = ((*it)->wrapS) ? sceneWidth : (*it)->surface.w; + uint h = ((*it)->wrapT) ? sceneHeight : (*it)->surface.h; + + const GLfloat vertices[] = { + (GLfloat) - (*it)->cameraX, (GLfloat) - (*it)->cameraY, 0.1f, + w - (*it)->cameraX, (GLfloat) - (*it)->cameraY, 0.1f, + (GLfloat) - (*it)->cameraX, h - (*it)->cameraY, 0.1f, + w - (*it)->cameraX, h - (*it)->cameraY, 0.1f + }; + + const GLfloat texCoords[] = { + 0.0f, 0.0f, + texw, 0.0f, + 0.0f, texh, + texw, texh + }; + drawQuad(shader.smartScaler, vertices, 1, texCoords); + + } +#endif + } +} + +void Parallax::save(Common::WriteStream *stream) { + ParallaxLayers::iterator it; + for (it = _parallaxLayers.begin(); it != _parallaxLayers.end(); ++it) { + stream->writeByte(1); + stream->writeUint16BE((*it)->fileNum); + stream->writeUint16BE((*it)->fractionX); + stream->writeUint16BE((*it)->fractionY); + } +} + void nosnapshot() { if (snapshotSurface.getPixels()) snapshotSurface.free(); @@ -122,16 +237,6 @@ void killLightMap() { lightMapNumber = 0; } -void killParallax() { - while (parallaxStuff) { - parallaxLayer *k = parallaxStuff; - parallaxStuff = k->next; - k->surface.free(); - delete k; - k = NULL; - } -} - bool reserveBackdrop() { cameraX = 0; cameraY = 0; @@ -147,7 +252,7 @@ bool reserveBackdrop() { void killAllBackDrop() { killLightMap(); killBackDrop(); - killParallax(); + g_sludge->_gfxMan->killParallax(); killZBuffer(); } @@ -265,44 +370,6 @@ void drawBackDrop() { // TODO: apply lightmap shader - // draw parallaxStuff - if (parallaxStuff) { - // TODO: simulate image repeating effect - warning("Drawing parallaxStuff"); -#if 0 - parallaxLayer *ps = parallaxStuff; - - // go to the parallax at bottom - while (ps->next) ps = ps->next; - - // draw parallax one by one - while (ps) { - 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; - - const GLfloat vertices[] = { - (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 - }; - - const GLfloat texCoords[] = { - 0.0f, 0.0f, - texw, 0.0f, - 0.0f, texh, - texw, texh - }; - drawQuad(shader.smartScaler, vertices, 1, texCoords); - - ps = ps->prev; - } -#endif - } - // draw backdrop Graphics::TransparentSurface tmp(backdropSurface, false); tmp.blit(renderSurface, 0, 0); @@ -331,67 +398,6 @@ bool loadLightMap(int v) { return true; } -bool loadParallax(uint16 v, uint16 fracX, uint16 fracY) { - setResourceForFatal(v); - if (!g_sludge->_resMan->openFileFromNum(v)) - return fatal("Can't open parallax image"); - - parallaxLayer *nP = new parallaxLayer; - if (!checkNew(nP)) - return false; - - nP->next = parallaxStuff; - parallaxStuff = nP; - if (nP->next) { - nP->next->prev = nP; - } - nP->prev = NULL; - - if (!ImgLoader::loadImage(g_sludge->_resMan->getData(), &nP->surface, 0)) - return false; - - nP->fileNum = v; - nP->fractionX = fracX; - nP->fractionY = fracY; - - // 65535 is the value of AUTOFIT constant in Sludge - if (fracX == 65535) { - nP->wrapS = false; - if (nP->surface.w < winWidth) { - fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen."); - return false; - } - } else { - nP->wrapS = true; - } - - if (fracY == 65535) { - nP->wrapT = false; - if (nP->surface.h < winHeight) { - fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen."); - return false; - } - } else { - nP->wrapT = true; - } - - // TODO: reinterpret this part -#if 0 - if (nP->wrapS) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - else - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - if (nP->wrapT) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - else - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#endif - - g_sludge->_resMan->finishAccess(); - setResourceForFatal(-1); - return true; -} - bool loadHSI(Common::SeekableReadStream *stream, int x, int y, bool reserve) { debug(kSludgeDebugGraphics, "Load HSI"); if (reserve) { @@ -452,15 +458,6 @@ void saveHSI(Common::WriteStream *stream) { Image::writePNG(*stream, backdropSurface); } -void saveParallaxRecursive(parallaxLayer *me, Common::WriteStream *stream) { - if (me) { - saveParallaxRecursive(me->next, stream); - stream->writeByte(1); - stream->writeUint16BE(me->fileNum); - stream->writeUint16BE(me->fractionX); - stream->writeUint16BE(me->fractionY); - } -} bool getRGBIntoStack(uint x, uint y, stackHandler *sH) { if (x >= sceneWidth || y >= sceneHeight) { diff --git a/engines/sludge/backdrop.h b/engines/sludge/backdrop.h index d2393563b3..5c406f55d9 100644 --- a/engines/sludge/backdrop.h +++ b/engines/sludge/backdrop.h @@ -23,6 +23,8 @@ #ifndef SLUDGE_BACKDROP_H #define SLUDGE_BACKDROP_H +#include "common/stream.h" + #include "graphics/surface.h" #include "sludge/variable.h" @@ -35,24 +37,33 @@ enum { LIGHTMAPMODE_PIXEL, LIGHTMAPMODE_NUM }; - extern uint winWidth, winHeight, sceneWidth, sceneHeight; extern int lightMapMode; - /** * parallax layers can scroll at different speeds * to the background image, giving the illusion of * depth to a scene as it moves. */ -struct parallaxLayer { - Graphics::Surface surface; - int speedX, speedY; - bool wrapS, wrapT; - uint16 fileNum, fractionX, fractionY; - int cameraX, cameraY; - parallaxLayer *next; - parallaxLayer *prev; +class Parallax { +public: + struct ParallaxLayer { + Graphics::Surface surface; + int speedX, speedY; + bool wrapS, wrapT; + uint16 fileNum, fractionX, fractionY; + int cameraX, cameraY; + }; + typedef Common::List ParallaxLayers; + + ~Parallax(); + + void kill(); + bool add(uint16 v, uint16 fracX, uint16 fracY); + void save(Common::WriteStream *fp); + void draw(); +private: + ParallaxLayers _parallaxLayers; }; void killAllBackDrop(); @@ -73,18 +84,11 @@ void hardScroll(int distance); bool getRGBIntoStack(uint x, uint y, stackHandler *sH); // Also the light map stuff - void killLightMap(); bool loadLightMap(int v); extern Graphics::Surface lightMap; -// And background parallax scrolling - -void killParallax(); -bool loadParallax(uint16 v, uint16 fracX, uint16 fracY); -void saveParallaxRecursive(parallaxLayer *me, Common::WriteStream *fp); - void nosnapshot(); bool snapshot(); void saveSnapshot(Common::WriteStream *stream); diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp index 7d5dadda14..02c68c08b8 100644 --- a/engines/sludge/builtin.cpp +++ b/engines/sludge/builtin.cpp @@ -50,6 +50,7 @@ #include "sludge/thumbnail.h" #include "sludge/sludge.h" #include "sludge/utf8.h" +#include "sludge/graphics.h" namespace Sludge { @@ -2358,7 +2359,7 @@ builtIn(parallaxAdd) { return BR_ERROR; trimStack(fun->stack); - if (!loadParallax(v, wrapX, wrapY)) + if (!g_sludge->_gfxMan->loadParallax(v, wrapX, wrapY)) return BR_ERROR; setVariable(fun->reg, SVT_INT, 1); } @@ -2367,7 +2368,7 @@ builtIn(parallaxAdd) { builtIn(parallaxClear) { UNUSEDALL - killParallax(); + g_sludge->_gfxMan->killParallax(); setVariable(fun->reg, SVT_INT, 1); return BR_CONTINUE; } diff --git a/engines/sludge/freeze.cpp b/engines/sludge/freeze.cpp index 35dcd56dca..080ced6dff 100644 --- a/engines/sludge/freeze.cpp +++ b/engines/sludge/freeze.cpp @@ -33,6 +33,7 @@ #include "sludge/fonttext.h" #include "sludge/statusba.h" #include "sludge/freeze.h" +#include "sludge/graphics.h" #include "sludge/zbuffer.h" namespace Sludge { @@ -44,7 +45,6 @@ extern speechStruct *speech; extern inputType input; extern Graphics::Surface backdropSurface; extern Graphics::Surface renderSurface; -extern parallaxLayer *parallaxStuff; extern int lightMapNumber, zBufferNumber; extern eventHandlers *currentEvents; extern personaAnimation *mouseCursorAnim; @@ -96,8 +96,8 @@ bool freeze() { newFreezer->lightMapSurface.copyFrom(lightMap); newFreezer->lightMapNumber = lightMapNumber; - newFreezer->parallaxStuff = parallaxStuff; - parallaxStuff = NULL; + newFreezer->parallaxStuff = g_sludge->_gfxMan->_parallaxStuff; + g_sludge->_gfxMan->_parallaxStuff = NULL; newFreezer->zBufferSprites = zBuffer.sprites; newFreezer->zBufferNumber = zBuffer.originalNum; newFreezer->zPanels = zBuffer.numPanels; @@ -196,8 +196,8 @@ void unfreeze(bool killImage) { setZBuffer(zBuffer.originalNum); } - killParallax(); - parallaxStuff = frozenStuff->parallaxStuff; + g_sludge->_gfxMan->killParallax(); + g_sludge->_gfxMan->_parallaxStuff = frozenStuff->parallaxStuff; deleteAnim(mouseCursorAnim); mouseCursorAnim = frozenStuff->mouseCursorAnim; diff --git a/engines/sludge/freeze.h b/engines/sludge/freeze.h index ae9cd6da1f..ad0d4266a2 100644 --- a/engines/sludge/freeze.h +++ b/engines/sludge/freeze.h @@ -33,7 +33,7 @@ struct frozenStuffStruct { Graphics::Surface lightMapSurface; Graphics::Surface *zBufferSprites; int zPanels; - parallaxLayer *parallaxStuff; + Parallax *parallaxStuff; int lightMapNumber, zBufferNumber; speechStruct *speech; statusStuff *frozenStatus; diff --git a/engines/sludge/graphics.cpp b/engines/sludge/graphics.cpp new file mode 100644 index 0000000000..93295b4f66 --- /dev/null +++ b/engines/sludge/graphics.cpp @@ -0,0 +1,61 @@ +/* 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. + * + */ + +#include "sludge/backdrop.h" +#include "sludge/graphics.h" + +namespace Sludge { + +GraphicsManager::GraphicsManager() { + _parallaxStuff = new Parallax; +} + +GraphicsManager::~GraphicsManager() { + delete _parallaxStuff; + _parallaxStuff = nullptr; +} + +bool GraphicsManager::loadParallax(uint16 v, uint16 fracX, uint16 fracY) { + if (!_parallaxStuff) + _parallaxStuff = new Parallax; + return _parallaxStuff->add(v, fracX, fracY); +} + +void GraphicsManager::killParallax() { + if (!_parallaxStuff) + return; + _parallaxStuff->kill(); +} + +void GraphicsManager::saveParallax(Common::WriteStream *fp) { + if (_parallaxStuff) + _parallaxStuff->save(fp); +} + +void GraphicsManager::drawParallax() { + if (_parallaxStuff) + _parallaxStuff->draw(); +} + + + +} // End of namespace Sludge diff --git a/engines/sludge/graphics.h b/engines/sludge/graphics.h new file mode 100644 index 0000000000..d866d9472a --- /dev/null +++ b/engines/sludge/graphics.h @@ -0,0 +1,46 @@ +/* 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. + * + */ + +#ifndef SLUDGE_GRAPHICS_H +#define SLUDGE_GRAPHICS_H + +namespace Sludge { + +class Parallax; + +class GraphicsManager { +public: + GraphicsManager(); + virtual ~GraphicsManager(); + + // Parallax + Parallax *_parallaxStuff; + bool loadParallax(uint16 v, uint16 fracX, uint16 fracY); + void killParallax(); + void saveParallax(Common::WriteStream *fp); + void drawParallax(); +}; + +} // End of namespace Sludge + + +#endif // SLUDGE_GRAPHICS_H diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp index 0ddb71c433..48fcfc3b93 100644 --- a/engines/sludge/loadsave.cpp +++ b/engines/sludge/loadsave.cpp @@ -46,6 +46,7 @@ #include "sludge/thumbnail.h" #include "sludge/utf8.h" #include "sludge/version.h" +#include "sludge/graphics.h" namespace Sludge { @@ -78,7 +79,6 @@ extern bool allowAnyFilename; extern uint16 saveEncoding; // in savedata.cpp extern byte currentBurnR, currentBurnG, currentBurnB; extern uint currentBlankColour; // in backdrop.cpp -extern parallaxLayer *parallaxStuff; // " extern int lightMapMode; // " //---------------------------------------------------------------------- @@ -460,7 +460,7 @@ bool saveGame(const Common::String &fname) { fp->writeByte(currentBurnG); fp->writeByte(currentBurnB); - saveParallaxRecursive(parallaxStuff, fp); + g_sludge->_gfxMan->saveParallax(fp); fp->writeByte(0); g_sludge->_languageMan->saveLanguageSetting(fp); @@ -658,7 +658,7 @@ bool loadGame(const Common::String &fname) { int fx = fp->readUint16BE(); int fy = fp->readUint16BE(); - if (!loadParallax(im, fx, fy)) + if (!g_sludge->_gfxMan->loadParallax(im, fx, fy)) return false; } diff --git a/engines/sludge/module.mk b/engines/sludge/module.mk index 491b17d028..ce45549990 100644 --- a/engines/sludge/module.mk +++ b/engines/sludge/module.mk @@ -11,6 +11,7 @@ MODULE_OBJS := \ floor.o \ freeze.o \ fonttext.o \ + graphics.o \ helpers.o \ hsi.o \ imgloader.o \ diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp index 34992ae33c..4c6c54df82 100644 --- a/engines/sludge/sludge.cpp +++ b/engines/sludge/sludge.cpp @@ -25,6 +25,7 @@ #include "common/debug-channels.h" #include "common/error.h" +#include "sludge/graphics.h" #include "sludge/sludge.h" #include "sludge/main_loop.h" @@ -65,6 +66,7 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc) _resMan = new ResourceManager(); _languageMan = new LanguageManager(); _objMan = new ObjectManager(this); + _gfxMan = new GraphicsManager(); } SludgeEngine::~SludgeEngine() { @@ -87,6 +89,8 @@ SludgeEngine::~SludgeEngine() { _pixelFormat = nullptr; // Dispose managers + delete _gfxMan; + _gfxMan = nullptr; delete _objMan; _objMan = nullptr; delete _languageMan; diff --git a/engines/sludge/sludge.h b/engines/sludge/sludge.h index cb2a509f6a..78cf1dfc10 100644 --- a/engines/sludge/sludge.h +++ b/engines/sludge/sludge.h @@ -38,6 +38,7 @@ namespace Sludge { extern SludgeEngine *g_sludge; +class GraphicsManager; class SludgeConsole; struct SludgeGameDescription; @@ -72,6 +73,7 @@ public: ResourceManager *_resMan; LanguageManager *_languageMan; ObjectManager *_objMan; + GraphicsManager *_gfxMan; SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc); virtual ~SludgeEngine(); -- cgit v1.2.3