From 52b627bae6f13586f2767d444a3946807b627973 Mon Sep 17 00:00:00 2001 From: yinsimei Date: Wed, 21 Jun 2017 16:24:55 +0200 Subject: SLUDGE: use Common::List to reproduce layer effects --- engines/sludge/freeze.cpp | 4 +-- engines/sludge/sludger.cpp | 18 +++++------ engines/sludge/sludger.h | 1 + engines/sludge/sprites.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++--- engines/sludge/sprites.h | 7 +++++ engines/sludge/zbuffer.cpp | 6 ++-- 6 files changed, 90 insertions(+), 20 deletions(-) diff --git a/engines/sludge/freeze.cpp b/engines/sludge/freeze.cpp index ddaaf9cc05..d3dde17bd5 100644 --- a/engines/sludge/freeze.cpp +++ b/engines/sludge/freeze.cpp @@ -74,9 +74,7 @@ void freezeGraphics() { int antiAlias = gameSettings.antiAlias; gameSettings.antiAlias = 0; #endif - drawBackDrop();// Draw the room - drawZBuffer(cameraX, cameraY, false); - drawPeople();// Then add any moving characters... + displayBase(); freezeSurface.copyFrom(renderSurface); #if 0 gameSettings.antiAlias = antiAlias; diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp index 4743649018..cf2a0539a1 100644 --- a/engines/sludge/sludger.cpp +++ b/engines/sludge/sludger.cpp @@ -572,6 +572,14 @@ bool checkColourChange(bool reset) { #endif return false; } + +void displayBase() { + drawBackDrop();// Draw the room + drawZBuffer(cameraX, cameraY, false); + drawPeople();// Then add any moving characters... + displaySpriteLayers(); +} + void sludgeDisplay() { #if 0 #if defined(HAVE_GLES2) @@ -666,15 +674,7 @@ void sludgeDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear The Screen glDepthMask(GL_FALSE); #endif - drawBackDrop();// Draw the room - drawZBuffer(cameraX, cameraY, false); -#if 0 - glEnable(GL_DEPTH_TEST); -#endif - drawPeople();// Then add any moving characters... -#if 0 - glDisable(GL_DEPTH_TEST); -#endif + displayBase(); viewSpeech();// ...and anything being said drawStatusBar(); displayCursor(); diff --git a/engines/sludge/sludger.h b/engines/sludge/sludger.h index 6234e591c2..10c17943c2 100644 --- a/engines/sludge/sludger.h +++ b/engines/sludge/sludger.h @@ -77,6 +77,7 @@ extern unsigned char *gameIcon; extern int iconW, iconH; bool initSludge(const char *); +void displayBase(); void sludgeDisplay(); int startNewFunctionNum(unsigned int, unsigned int, loadedFunction *, variableStack*&, bool = true); bool handleInput(); diff --git a/engines/sludge/sprites.cpp b/engines/sludge/sprites.cpp index a8f5ed2f08..c457410ec9 100644 --- a/engines/sludge/sprites.cpp +++ b/engines/sludge/sprites.cpp @@ -40,6 +40,26 @@ namespace Sludge { +// Sprite display informations +struct SpriteDisplay { + int x, y; + int width, height; + Graphics::FLIP_FLAGS flip; + Graphics::Surface *surface; + + SpriteDisplay(int xpos, int ypos, Graphics::FLIP_FLAGS f, Graphics::Surface *ptr, int w = -1, int h = 1) : + x(xpos), y(ypos), flip(f), surface(ptr), width(w), height(h) { + } +}; + +// All sprites are sorted into different "layers" (up to 16) according to their relative y position to z-buffer zones +struct SpriteLayers { + int numLayers; + Common::List layer[16]; +}; + +SpriteLayers spriteLayers; + extern zBufferData zBuffer; #if 0 @@ -639,14 +659,20 @@ bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *t } // Use Transparent surface to scale and blit - Graphics::TransparentSurface tmp(single.surface, false); - tmp.blit(renderSurface, x1, y1, (mirror? Graphics::FLIP_H : Graphics::FLIP_NONE), nullptr, TS_ARGB(255, 255, 255, 255), diffX, diffY); + if (!zBuffer.numPanels) { + Graphics::TransparentSurface tmp(single.surface, false); + tmp.blit(renderSurface, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), nullptr, TS_ARGB(255, 255, 255, 255), diffX, diffY); + } else { + int d = ((!(thisPerson->extra & EXTRA_NOZB)) && zBuffer.numPanels) ? y + cameraY : sceneHeight + 1; + addSpriteDepth(&single.surface, d, x1, y1, (mirror ? Graphics::FLIP_H : Graphics::FLIP_NONE), diffX, diffY); + } // Are we pointing at the sprite? if (input.mouseX >= x1 && input.mouseX <= x2 && input.mouseY >= y1 && input.mouseY <= y2) { - if (thisPerson->extra & EXTRA_RECTANGULAR) return true; + if (thisPerson->extra & EXTRA_RECTANGULAR) return true; - } + return true; + } return false; #if 0 @@ -782,6 +808,46 @@ bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *t #endif } +void resetSpriteLayers(zBufferData *pz, int x, int y, bool upsidedown) { + if (spriteLayers.numLayers > 0) + killSpriteLayers(); + spriteLayers.numLayers = pz->numPanels; + for (int i = 0; i < spriteLayers.numLayers; ++i) { + SpriteDisplay node(x, y, (upsidedown ? Graphics::FLIP_V : Graphics::FLIP_NONE), &pz->sprites[i], pz->sprites[i].w, pz->sprites[i].h); + spriteLayers.layer[i].push_back(node); + } +} + +void addSpriteDepth(Graphics::Surface *ptr, int depth, int x, int y, Graphics::FLIP_FLAGS flip, int width, int height) { + int i; + for (i = 1; i < zBuffer.numPanels; ++i) { + if (zBuffer.panel[i] >= depth) { + break; + } + } + --i; + SpriteDisplay node(x, y, flip, ptr, width, height); + spriteLayers.layer[i].push_back(node); +} + +void displaySpriteLayers() { + for (int i = 0; i < spriteLayers.numLayers; ++i) { + Common::List::iterator it; + for (it = spriteLayers.layer[i].begin(); it != spriteLayers.layer[i].end(); ++it) { + Graphics::TransparentSurface tmp(*it->surface, false); + tmp.blit(renderSurface, it->x, it->y, it->flip, nullptr, TS_ARGB(255, 255, 255, 255), it->width, it->height); + } + } + killSpriteLayers(); +} + +void killSpriteLayers() { + for (int i = 0; i < spriteLayers.numLayers; ++i) { + spriteLayers.layer[i].clear(); + } + spriteLayers.numLayers = 0; +} + // Paste a scaled sprite onto the backdrop void fixScaleSprite(int x, int y, sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, int camX, int camY, bool mirror) { #if 0 diff --git a/engines/sludge/sprites.h b/engines/sludge/sprites.h index f3ec22dc25..effb5121a3 100644 --- a/engines/sludge/sprites.h +++ b/engines/sludge/sprites.h @@ -23,10 +23,12 @@ #define SLUDGE_SPRITE_H #include "graphics/surface.h" +#include "graphics/transparent_surface.h" namespace Sludge { struct onScreenPerson; +struct zBufferData; struct sprite { int xhot, yhot; @@ -75,6 +77,11 @@ bool reserveSpritePal(spritePalette &sP, int n); void fixScaleSprite(int x1, int y1, sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, const int camX, const int camY, bool); void burnSpriteToBackDrop(int x1, int y1, sprite &single, const spritePalette &fontPal); +void resetSpriteLayers(zBufferData *ptrZBuffer, int x, int y, bool upsidedown); +void addSpriteDepth(Graphics::Surface *ptr, int depth, int x, int y, Graphics::FLIP_FLAGS flip, int width = -1, int height = -1); +void displaySpriteLayers(); +void killSpriteLayers(); + } // End of namespace Sludge #endif diff --git a/engines/sludge/zbuffer.cpp b/engines/sludge/zbuffer.cpp index cc3bb8d67f..76fa515de2 100644 --- a/engines/sludge/zbuffer.cpp +++ b/engines/sludge/zbuffer.cpp @@ -31,6 +31,7 @@ #include "sludge/newfatal.h" #include "sludge/graphics.h" #include "sludge/sludge.h" +#include "sludge/sprites.h" namespace Sludge { @@ -170,10 +171,7 @@ void drawZBuffer(int x, int y, bool upsidedown) { if (!zBuffer.numPanels || !zBuffer.sprites) return; - for (int i = 0; i < zBuffer.numPanels; ++i) { - Graphics::TransparentSurface tmp(zBuffer.sprites[i], false); - tmp.blit(renderSurface, 0, 0, (upsidedown ? Graphics::FLIP_V : Graphics::FLIP_NONE)); - } + resetSpriteLayers(&zBuffer, x, y, upsidedown); #if 0 glEnable (GL_DEPTH_TEST); -- cgit v1.2.3