2014-12-25 08:29:38 +00: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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2014-12-26 03:37:20 +00:00
|
|
|
#include "common/system.h"
|
|
|
|
#include "graphics/palette.h"
|
2014-12-31 08:50:24 +00:00
|
|
|
#include "graphics/surface.h"
|
2014-12-25 08:29:38 +00:00
|
|
|
#include "xeen/screen.h"
|
2014-12-26 02:10:30 +00:00
|
|
|
#include "xeen/resources.h"
|
2014-12-26 03:37:20 +00:00
|
|
|
#include "xeen/xeen.h"
|
2014-12-25 08:29:38 +00:00
|
|
|
|
|
|
|
namespace Xeen {
|
|
|
|
|
2016-09-20 02:53:59 +00:00
|
|
|
XeenEngine *Window::_vm;
|
|
|
|
|
|
|
|
void Window::init(XeenEngine *vm) {
|
|
|
|
_vm = vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
Window::Window() : XSurface(), _enabled(false),
|
2016-09-05 02:37:42 +00:00
|
|
|
_a(0), _border(0), _xLo(0), _xHi(0), _ycL(0), _ycH(0) {
|
2014-12-30 08:09:21 +00:00
|
|
|
}
|
2014-12-30 07:20:40 +00:00
|
|
|
|
2016-09-20 02:53:59 +00:00
|
|
|
Window::Window(const Window &src) : XSurface(), _enabled(src._enabled),
|
2016-09-05 01:16:51 +00:00
|
|
|
_a(src._a), _border(src._border), _xLo(src._xLo), _ycL(src._ycL),
|
|
|
|
_xHi(src._xHi), _ycH(src._ycH) {
|
2016-09-20 02:53:59 +00:00
|
|
|
|
|
|
|
setBounds(src._bounds);
|
|
|
|
create(*_vm->_screen, Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
|
2016-09-05 01:16:51 +00:00
|
|
|
}
|
|
|
|
|
2016-09-20 02:53:59 +00:00
|
|
|
Window::Window(const Common::Rect &bounds, int a, int border,
|
2016-09-05 02:37:42 +00:00
|
|
|
int xLo, int ycL, int xHi, int ycH): XSurface(),
|
2016-09-20 02:53:59 +00:00
|
|
|
_enabled(false), _a(a), _border(border),
|
2014-12-31 08:50:24 +00:00
|
|
|
_xLo(xLo), _ycL(ycL), _xHi(xHi), _ycH(ycH) {
|
|
|
|
setBounds(bounds);
|
2016-09-05 01:16:51 +00:00
|
|
|
create(*_vm->_screen, Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
|
2014-12-30 07:20:40 +00:00
|
|
|
}
|
|
|
|
|
2014-12-31 08:50:24 +00:00
|
|
|
void Window::setBounds(const Common::Rect &r) {
|
|
|
|
_bounds = r;
|
|
|
|
_innerBounds = r;
|
|
|
|
_innerBounds.grow(-_border);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::open() {
|
|
|
|
if (!_enabled) {
|
2015-01-01 07:09:13 +00:00
|
|
|
_enabled = true;
|
2014-12-31 08:50:24 +00:00
|
|
|
_vm->_screen->_windowStack.push_back(this);
|
|
|
|
open2();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_vm->_mode == MODE_9) {
|
|
|
|
warning("TODO: copyFileToMemory");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::open2() {
|
2015-01-29 01:59:01 +00:00
|
|
|
Screen &screen = *_vm->_screen;
|
|
|
|
|
|
|
|
// Save a copy of the area under the window
|
|
|
|
_savedArea.create(_bounds.width(), _bounds.height());
|
|
|
|
_savedArea.copyRectToSurface(screen, 0, 0, _bounds);
|
|
|
|
|
|
|
|
// Mark the area as dirty and fill it with a default background
|
2015-01-01 21:46:22 +00:00
|
|
|
addDirtyRect(_bounds);
|
2014-12-31 21:12:18 +00:00
|
|
|
frame();
|
2015-01-01 07:09:13 +00:00
|
|
|
fill();
|
2015-01-29 01:09:15 +00:00
|
|
|
|
|
|
|
screen._writePos.x = _bounds.right - 8;
|
|
|
|
screen.writeSymbol(19);
|
|
|
|
|
|
|
|
screen._writePos.x = _innerBounds.left;
|
|
|
|
screen._writePos.y = _innerBounds.top;
|
|
|
|
screen._fontJustify = JUSTIFY_NONE;
|
|
|
|
screen._fontReduced = false;
|
2014-12-31 21:12:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Window::frame() {
|
|
|
|
Screen &screen = *_vm->_screen;
|
2015-01-01 02:14:45 +00:00
|
|
|
int xCount = (_bounds.width() - 9) / FONT_WIDTH;
|
|
|
|
int yCount = (_bounds.height() - 9) / FONT_HEIGHT;
|
2014-12-31 21:12:18 +00:00
|
|
|
|
|
|
|
// Write the top line
|
|
|
|
screen._writePos = Common::Point(_bounds.left, _bounds.top);
|
|
|
|
screen.writeSymbol(0);
|
|
|
|
|
|
|
|
if (xCount > 0) {
|
|
|
|
int symbolId = 1;
|
|
|
|
for (int i = 0; i < xCount; ++i) {
|
|
|
|
screen.writeSymbol(symbolId);
|
|
|
|
if (++symbolId == 5)
|
|
|
|
symbolId = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-01 02:14:45 +00:00
|
|
|
screen._writePos.x = _bounds.right - FONT_WIDTH;
|
2014-12-31 21:12:18 +00:00
|
|
|
screen.writeSymbol(5);
|
|
|
|
|
|
|
|
// Write the vertical edges
|
|
|
|
if (yCount > 0) {
|
|
|
|
int symbolId = 6;
|
|
|
|
for (int i = 0; i < yCount; ++i) {
|
|
|
|
screen._writePos.y += 8;
|
|
|
|
|
|
|
|
screen._writePos.x = _bounds.left;
|
|
|
|
screen.writeSymbol(symbolId);
|
|
|
|
|
2015-01-01 02:14:45 +00:00
|
|
|
screen._writePos.x = _bounds.right - FONT_WIDTH;
|
2014-12-31 21:12:18 +00:00
|
|
|
screen.writeSymbol(symbolId + 4);
|
|
|
|
|
|
|
|
if (++symbolId == 10)
|
|
|
|
symbolId = 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write the bottom line
|
2015-01-01 02:14:45 +00:00
|
|
|
screen._writePos = Common::Point(_bounds.left, _bounds.bottom - FONT_HEIGHT);
|
2014-12-31 21:12:18 +00:00
|
|
|
screen.writeSymbol(14);
|
|
|
|
|
|
|
|
if (xCount > 0) {
|
|
|
|
int symbolId = 15;
|
|
|
|
for (int i = 0; i < xCount; ++i) {
|
|
|
|
screen.writeSymbol(symbolId);
|
|
|
|
if (++symbolId == 19)
|
|
|
|
symbolId = 15;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-01 02:14:45 +00:00
|
|
|
screen._writePos.x = _bounds.right - FONT_WIDTH;
|
2014-12-31 21:12:18 +00:00
|
|
|
screen.writeSymbol(19);
|
2014-12-31 08:50:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Window::close() {
|
2015-01-29 01:59:01 +00:00
|
|
|
Screen &screen = *_vm->_screen;
|
|
|
|
|
2014-12-31 08:50:24 +00:00
|
|
|
if (_enabled) {
|
2015-01-29 01:59:01 +00:00
|
|
|
// Update the window
|
2014-12-31 08:50:24 +00:00
|
|
|
update();
|
|
|
|
|
2015-01-29 01:59:01 +00:00
|
|
|
// Restore the saved original content
|
|
|
|
screen.copyRectToSurface(_savedArea, _bounds.left, _bounds.top,
|
|
|
|
Common::Rect(0, 0, _bounds.width(), _bounds.height()));
|
|
|
|
addDirtyRect(_bounds);
|
|
|
|
|
2014-12-31 08:50:24 +00:00
|
|
|
// Remove the window from the stack and flag it as now disabled
|
|
|
|
for (uint i = 0; i < _vm->_screen->_windowStack.size(); ++i) {
|
|
|
|
if (_vm->_screen->_windowStack[i] == this)
|
|
|
|
_vm->_screen->_windowStack.remove_at(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
_enabled = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_vm->_mode == MODE_9) {
|
|
|
|
warning("TODO: copyFileToMemory");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-31 03:28:53 +00:00
|
|
|
void Window::update() {
|
2015-01-01 21:46:22 +00:00
|
|
|
// Since all window drawing is done on the screen surface anyway,
|
|
|
|
// there's nothing that needs to be updated here
|
2014-12-31 03:28:53 +00:00
|
|
|
}
|
|
|
|
|
2014-12-31 21:12:18 +00:00
|
|
|
void Window::addDirtyRect(const Common::Rect &r) {
|
2015-01-01 21:46:22 +00:00
|
|
|
_vm->_screen->addDirtyRect(r);
|
2014-12-31 21:12:18 +00:00
|
|
|
}
|
|
|
|
|
2015-01-01 02:14:45 +00:00
|
|
|
void Window::fill() {
|
2015-01-01 02:27:37 +00:00
|
|
|
fillRect(_innerBounds, _vm->_screen->_bgColor);
|
2015-01-01 02:14:45 +00:00
|
|
|
}
|
|
|
|
|
2015-03-03 04:13:01 +00:00
|
|
|
const char *Window::writeString(const Common::String &s) {
|
2015-03-03 02:39:49 +00:00
|
|
|
return _vm->_screen->writeString(s, _innerBounds);
|
2015-01-01 02:14:45 +00:00
|
|
|
}
|
|
|
|
|
2015-01-05 13:11:16 +00:00
|
|
|
void Window::drawList(DrawStruct *items, int count) {
|
|
|
|
for (int i = 0; i < count; ++i, ++items) {
|
2015-01-14 13:48:16 +00:00
|
|
|
if (items->_frame == -1 || items->_scale == -1 || items->_sprites == nullptr)
|
2015-01-04 00:08:30 +00:00
|
|
|
continue;
|
2015-01-24 20:14:57 +00:00
|
|
|
|
2015-02-01 20:24:12 +00:00
|
|
|
Common::Point pt(items->_x, items->_y);
|
|
|
|
pt.x += _innerBounds.left;
|
|
|
|
pt.y += _innerBounds.top;
|
|
|
|
|
|
|
|
items->_sprites->draw(*this, items->_frame, pt, items->_flags, items->_scale);
|
2015-01-04 00:08:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-30 07:20:40 +00:00
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
|
2014-12-25 08:29:38 +00:00
|
|
|
Screen::Screen(XeenEngine *vm) : _vm(vm) {
|
2016-09-20 02:53:59 +00:00
|
|
|
Window::init(vm);
|
2014-12-26 22:07:25 +00:00
|
|
|
_fadeIn = false;
|
2014-12-26 07:31:05 +00:00
|
|
|
create(SCREEN_WIDTH, SCREEN_HEIGHT);
|
2015-01-01 07:09:13 +00:00
|
|
|
Common::fill(&_tempPalette[0], &_tempPalette[PALETTE_SIZE], 0);
|
|
|
|
Common::fill(&_mainPalette[0], &_mainPalette[PALETTE_SIZE], 0);
|
2015-01-01 02:14:45 +00:00
|
|
|
|
|
|
|
// Load font data for the screen
|
|
|
|
File f("fnt");
|
|
|
|
byte *data = new byte[f.size()];
|
|
|
|
f.read(data, f.size());
|
|
|
|
_fontData = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
Screen::~Screen() {
|
|
|
|
delete[] _fontData;
|
2014-12-30 08:09:21 +00:00
|
|
|
}
|
2014-12-30 07:20:40 +00:00
|
|
|
|
2014-12-30 08:09:21 +00:00
|
|
|
void Screen::setupWindows() {
|
2014-12-30 20:22:05 +00:00
|
|
|
Window windows[40] = {
|
2016-09-20 02:53:59 +00:00
|
|
|
Window(Common::Rect(0, 0, 320, 200), 0, 0, 0, 0, 320, 200),
|
|
|
|
Window(Common::Rect(237, 9, 317, 74), 0, 0, 237, 12, 307, 68),
|
|
|
|
Window(Common::Rect(225, 1, 319, 73), 1, 8, 225, 1, 319, 73),
|
|
|
|
Window(Common::Rect(0, 0, 230, 149), 0, 0, 9, 8, 216, 140),
|
|
|
|
Window(Common::Rect(235, 148, 309, 189), 2, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(70, 20, 250, 183), 3, 8, 80, 38, 240, 166),
|
|
|
|
Window(Common::Rect(52, 149, 268, 197), 4, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(108, 0, 200, 200), 5, 0, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(232, 9, 312, 74), 0, 0, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(103, 156, 217, 186), 6, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(226, 0, 319, 146), 7, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(8, 8, 224, 140), 8, 8, 8, 8, 224, 200),
|
|
|
|
Window(Common::Rect(0, 143, 320, 199), 9, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(50, 103, 266, 139), 10, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(0, 7, 320, 138), 11, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(50, 71, 182, 129), 12, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(228, 106, 319, 146), 13, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(20, 142, 290, 199), 14, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(0, 20, 320, 180), 15, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(231, 48, 317, 141), 16, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(72, 37, 248, 163), 17, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(99, 59, 237, 141), 18, 8, 99, 59, 237, 0),
|
|
|
|
Window(Common::Rect(65, 23, 250, 163), 19, 8, 75, 36, 245, 141),
|
|
|
|
Window(Common::Rect(80, 28, 256, 148), 20, 8, 80, 28, 256, 172),
|
|
|
|
Window(Common::Rect(0, 0, 320, 146), 21, 8, 0, 0, 320, 148),
|
|
|
|
Window(Common::Rect(27, 6, 207, 142), 22, 8, 0, 0, 0, 146),
|
|
|
|
Window(Common::Rect(15, 15, 161, 91), 23, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(90, 45, 220, 157), 24, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(0, 0, 320, 200), 25, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(0, 101, 320, 146), 26, 8, 0, 101, 320, 0),
|
|
|
|
Window(Common::Rect(0, 0, 320, 108), 27, 8, 0, 0, 0, 45),
|
|
|
|
Window(Common::Rect(50, 112, 266, 148), 28, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(12, 11, 164, 94), 0, 0, 0, 0, 52, 0),
|
|
|
|
Window(Common::Rect(8, 147, 224, 192), 0, 8, 0, 0, 0, 94),
|
|
|
|
Window(Common::Rect(232, 74, 312, 138), 29, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(226, 26, 319, 146), 30, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(225, 74, 319, 154), 31, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(27, 6, 195, 142), 0, 8, 0, 0, 0, 0),
|
|
|
|
Window(Common::Rect(225, 140, 319, 199), 0, 8, 0, 0, 0, 0)
|
2014-12-30 08:09:21 +00:00
|
|
|
};
|
|
|
|
|
2014-12-30 20:22:05 +00:00
|
|
|
_windows = Common::Array<Window>(windows, 40);
|
2014-12-25 08:29:38 +00:00
|
|
|
}
|
|
|
|
|
2014-12-31 08:50:24 +00:00
|
|
|
void Screen::closeWindows() {
|
|
|
|
for (int i = (int)_windowStack.size() - 1; i >= 0; --i)
|
|
|
|
_windowStack[i]->close();
|
|
|
|
assert(_windowStack.size() == 0);
|
|
|
|
}
|
|
|
|
|
2014-12-25 08:29:38 +00:00
|
|
|
void Screen::update() {
|
2014-12-25 09:56:35 +00:00
|
|
|
// Merge the dirty rects
|
|
|
|
mergeDirtyRects();
|
|
|
|
|
|
|
|
// Loop through copying dirty areas to the physical screen
|
|
|
|
Common::List<Common::Rect>::iterator i;
|
|
|
|
for (i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) {
|
|
|
|
const Common::Rect &r = *i;
|
|
|
|
const byte *srcP = (const byte *)getBasePtr(r.left, r.top);
|
|
|
|
g_system->copyRectToScreen(srcP, this->pitch, r.left, r.top,
|
|
|
|
r.width(), r.height());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Signal the physical screen to update
|
2014-12-25 08:29:38 +00:00
|
|
|
g_system->updateScreen();
|
2014-12-25 09:56:35 +00:00
|
|
|
_dirtyRects.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::addDirtyRect(const Common::Rect &r) {
|
2015-01-15 03:10:32 +00:00
|
|
|
assert(r.isValidRect() && r.width() > 0 && r.height() > 0
|
|
|
|
&& r.left >= 0 && r.top >= 0
|
2015-01-01 08:55:10 +00:00
|
|
|
&& r.right <= SCREEN_WIDTH && r.bottom <= SCREEN_HEIGHT);
|
2014-12-25 09:56:35 +00:00
|
|
|
_dirtyRects.push_back(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::mergeDirtyRects() {
|
|
|
|
Common::List<Common::Rect>::iterator rOuter, rInner;
|
|
|
|
|
|
|
|
// Ensure dirty rect list has at least two entries
|
|
|
|
rOuter = _dirtyRects.begin();
|
|
|
|
for (int i = 0; i < 2; ++i, ++rOuter) {
|
|
|
|
if (rOuter == _dirtyRects.end())
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process the dirty rect list to find any rects to merge
|
|
|
|
for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
|
|
|
|
rInner = rOuter;
|
|
|
|
while (++rInner != _dirtyRects.end()) {
|
|
|
|
|
|
|
|
if ((*rOuter).intersects(*rInner)) {
|
|
|
|
// these two rectangles overlap or
|
|
|
|
// are next to each other - merge them
|
|
|
|
|
|
|
|
unionRectangle(*rOuter, *rOuter, *rInner);
|
|
|
|
|
|
|
|
// remove the inner rect from the list
|
|
|
|
_dirtyRects.erase(rInner);
|
|
|
|
|
|
|
|
// move back to beginning of list
|
|
|
|
rInner = rOuter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) {
|
|
|
|
destRect = src1;
|
|
|
|
destRect.extend(src2);
|
|
|
|
|
|
|
|
return !destRect.isEmpty();
|
2014-12-25 08:29:38 +00:00
|
|
|
}
|
|
|
|
|
2014-12-26 02:10:30 +00:00
|
|
|
void Screen::loadPalette(const Common::String &name) {
|
|
|
|
File f(name);
|
2014-12-26 07:31:05 +00:00
|
|
|
for (int i = 0; i < PALETTE_SIZE; ++i)
|
2015-01-01 07:09:13 +00:00
|
|
|
_tempPalette[i] = f.readByte() << 2;
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::loadBackground(const Common::String &name) {
|
|
|
|
File f(name);
|
|
|
|
|
|
|
|
assert(f.size() == (SCREEN_WIDTH * SCREEN_HEIGHT));
|
2014-12-26 03:37:20 +00:00
|
|
|
f.read((byte *)getPixels(), SCREEN_WIDTH * SCREEN_HEIGHT);
|
2015-01-01 21:46:22 +00:00
|
|
|
addDirtyRect(Common::Rect(0, 0, this->w, this->h));
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::loadPage(int pageNum) {
|
|
|
|
assert(pageNum == 0 || pageNum == 1);
|
|
|
|
if (_pages[0].empty()) {
|
|
|
|
_pages[0].create(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
|
|
_pages[1].create(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
|
|
}
|
|
|
|
|
2016-09-05 01:16:51 +00:00
|
|
|
_pages[pageNum].blitFrom(*this);
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
|
2014-12-26 22:07:25 +00:00
|
|
|
void Screen::freePages() {
|
|
|
|
_pages[0].free();
|
|
|
|
_pages[1].free();
|
|
|
|
}
|
|
|
|
|
2014-12-26 02:10:30 +00:00
|
|
|
void Screen::horizMerge(int xp) {
|
|
|
|
if (_pages[0].empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (int y = 0; y < SCREEN_HEIGHT; ++y) {
|
2014-12-26 03:37:20 +00:00
|
|
|
byte *destP = (byte *)getBasePtr(0, y);
|
2016-09-19 01:12:46 +00:00
|
|
|
const byte *srcP = (const byte *)_pages[0].getBasePtr(xp, y);
|
2014-12-26 02:10:30 +00:00
|
|
|
Common::copy(srcP, srcP + SCREEN_WIDTH - xp, destP);
|
|
|
|
|
|
|
|
if (xp != 0) {
|
2016-09-19 01:12:46 +00:00
|
|
|
destP = (byte *)getBasePtr(SCREEN_WIDTH - xp, y);
|
2014-12-26 07:57:58 +00:00
|
|
|
srcP = (const byte *)_pages[1].getBasePtr(0, y);
|
2016-09-19 01:12:46 +00:00
|
|
|
Common::copy(srcP, srcP + xp, destP);
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-19 01:12:46 +00:00
|
|
|
|
|
|
|
markAllDirty();
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::vertMerge(int yp) {
|
|
|
|
if (_pages[0].empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (int y = 0; y < SCREEN_HEIGHT - yp; ++y) {
|
|
|
|
const byte *srcP = (const byte *)_pages[0].getBasePtr(0, y);
|
2014-12-26 03:37:20 +00:00
|
|
|
byte *destP = (byte *)getBasePtr(0, y);
|
2014-12-26 02:10:30 +00:00
|
|
|
Common::copy(srcP, srcP + SCREEN_WIDTH, destP);
|
|
|
|
}
|
|
|
|
|
2016-09-19 01:12:46 +00:00
|
|
|
for (int y = 0; y < (SCREEN_HEIGHT - yp); ++y) {
|
2014-12-26 02:10:30 +00:00
|
|
|
const byte *srcP = (const byte *)_pages[1].getBasePtr(0, y);
|
2016-09-19 01:12:46 +00:00
|
|
|
byte *destP = (byte *)getBasePtr(0, SCREEN_HEIGHT - yp + y);
|
2014-12-26 02:10:30 +00:00
|
|
|
Common::copy(srcP, srcP + SCREEN_WIDTH, destP);
|
|
|
|
}
|
2016-09-19 01:12:46 +00:00
|
|
|
|
|
|
|
markAllDirty();
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::draw(void *data) {
|
|
|
|
// TODO: Figure out data structure that can be passed to method
|
|
|
|
assert(!data);
|
2014-12-26 03:37:20 +00:00
|
|
|
drawScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::drawScreen() {
|
|
|
|
addDirtyRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
|
|
|
|
}
|
|
|
|
|
2014-12-30 07:20:40 +00:00
|
|
|
void Screen::fadeIn(int step) {
|
2014-12-26 22:07:25 +00:00
|
|
|
_fadeIn = true;
|
2014-12-26 03:37:20 +00:00
|
|
|
fadeInner(step);
|
|
|
|
}
|
|
|
|
|
2014-12-26 22:07:25 +00:00
|
|
|
void Screen::fadeOut(int step) {
|
|
|
|
_fadeIn = false;
|
2014-12-26 03:37:20 +00:00
|
|
|
fadeInner(step);
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
|
2014-12-26 03:37:20 +00:00
|
|
|
void Screen::fadeInner(int step) {
|
2014-12-26 22:07:25 +00:00
|
|
|
for (int idx = 128; idx >= 0 && !_vm->shouldQuit(); idx -= step) {
|
|
|
|
int val = MAX(idx, 0);
|
|
|
|
bool flag = !_fadeIn;
|
2014-12-26 03:37:20 +00:00
|
|
|
if (!flag) {
|
|
|
|
val = -(val - 128);
|
|
|
|
flag = step != 0x81;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!flag) {
|
|
|
|
step = 0x80;
|
|
|
|
} else {
|
|
|
|
// Create a scaled palette from the temporary one
|
|
|
|
for (int i = 0; i < PALETTE_SIZE; ++i) {
|
2015-01-01 07:09:13 +00:00
|
|
|
_mainPalette[i] = (_tempPalette[i] * val * 2) >> 8;
|
2014-12-26 03:37:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
updatePalette();
|
|
|
|
}
|
2014-12-26 07:31:05 +00:00
|
|
|
|
|
|
|
_vm->_events->pollEventsAndWait();
|
2014-12-26 03:37:20 +00:00
|
|
|
}
|
2016-09-18 15:30:41 +00:00
|
|
|
|
|
|
|
update();
|
2014-12-26 03:37:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::updatePalette() {
|
|
|
|
updatePalette(_mainPalette, 0, 16);
|
|
|
|
}
|
2014-12-26 02:10:30 +00:00
|
|
|
|
2014-12-26 03:37:20 +00:00
|
|
|
void Screen::updatePalette(const byte *pal, int start, int count16) {
|
|
|
|
g_system->getPaletteManager()->setPalette(pal, start, count16 * 16);
|
2014-12-26 02:10:30 +00:00
|
|
|
}
|
|
|
|
|
2014-12-30 07:20:40 +00:00
|
|
|
void Screen::saveBackground(int slot) {
|
2014-12-26 22:07:25 +00:00
|
|
|
assert(slot > 0 && slot < 10);
|
|
|
|
_savedScreens[slot - 1].copyFrom(*this);
|
|
|
|
}
|
|
|
|
|
2014-12-30 07:20:40 +00:00
|
|
|
void Screen::restoreBackground(int slot) {
|
2014-12-26 22:07:25 +00:00
|
|
|
assert(slot > 0 && slot < 10);
|
|
|
|
|
2016-09-05 01:16:51 +00:00
|
|
|
blitFrom(_savedScreens[slot - 1]);
|
2014-12-26 22:07:25 +00:00
|
|
|
}
|
|
|
|
|
2015-02-10 03:01:01 +00:00
|
|
|
void Screen::frameWindow(uint bgType) {
|
|
|
|
if (bgType >= 4)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (bgType == 0) {
|
|
|
|
// Totally black background
|
|
|
|
_vm->_screen->fillRect(Common::Rect(8, 8, 224, 140), 0);
|
|
|
|
} else {
|
|
|
|
const byte *lookup = BACKGROUND_XLAT + bgType;
|
|
|
|
for (int yp = 8; yp < 140; ++yp) {
|
|
|
|
byte *destP = (byte *)_vm->_screen->getBasePtr(8, yp);
|
|
|
|
for (int xp = 8; xp < 224; ++xp, ++destP)
|
|
|
|
*destP = lookup[*destP];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-12-26 22:07:25 +00:00
|
|
|
|
2014-12-25 08:29:38 +00:00
|
|
|
} // End of namespace Xeen
|