2005-01-17 10:57:15 +00:00
|
|
|
/* Copyright (C) 1994-1998 Revolution Software Ltd.
|
2006-01-18 17:39:49 +00:00
|
|
|
* Copyright (C) 2003-2006 The ScummVM project
|
2003-07-28 01:47:41 +00:00
|
|
|
*
|
|
|
|
* 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
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2003-07-28 01:47:41 +00:00
|
|
|
*
|
2006-02-09 15:12:44 +00:00
|
|
|
* $URL$
|
|
|
|
* $Id$
|
2003-07-28 01:47:41 +00:00
|
|
|
*/
|
|
|
|
|
2003-11-16 14:18:29 +00:00
|
|
|
#include "common/stdafx.h"
|
2006-03-29 15:59:37 +00:00
|
|
|
#include "common/endian.h"
|
2005-01-10 22:06:49 +00:00
|
|
|
#include "common/system.h"
|
2005-02-27 16:11:19 +00:00
|
|
|
|
2005-04-27 20:29:19 +00:00
|
|
|
#include "graphics/primitives.h"
|
|
|
|
|
2003-10-28 19:51:30 +00:00
|
|
|
#include "sword2/sword2.h"
|
2005-02-27 16:11:19 +00:00
|
|
|
#include "sword2/defs.h"
|
2006-02-12 19:33:45 +00:00
|
|
|
#include "sword2/screen.h"
|
2005-03-11 15:30:28 +00:00
|
|
|
|
2003-10-04 00:52:27 +00:00
|
|
|
namespace Sword2 {
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2005-02-19 14:02:16 +00:00
|
|
|
#define MILLISECSPERCYCLE 83
|
|
|
|
#define RENDERAVERAGETOTAL 4
|
2003-10-15 06:40:31 +00:00
|
|
|
|
2005-02-19 14:02:16 +00:00
|
|
|
void Screen::updateRect(Common::Rect *r) {
|
2004-03-28 16:30:50 +00:00
|
|
|
_vm->_system->copyRectToScreen(_buffer + r->top * _screenWide + r->left,
|
2003-10-15 06:40:31 +00:00
|
|
|
_screenWide, r->left, r->top, r->right - r->left,
|
|
|
|
r->bottom - r->top);
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
|
|
|
|
2005-02-19 14:02:16 +00:00
|
|
|
void Screen::blitBlockSurface(BlockSurface *s, Common::Rect *r, Common::Rect *clipRect) {
|
2004-01-09 07:53:08 +00:00
|
|
|
if (!r->intersects(*clipRect))
|
2003-08-17 14:07:16 +00:00
|
|
|
return;
|
|
|
|
|
2003-08-28 06:36:15 +00:00
|
|
|
byte *src = s->data;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2004-01-09 07:53:08 +00:00
|
|
|
if (r->top < clipRect->top) {
|
|
|
|
src -= BLOCKWIDTH * (r->top - clipRect->top);
|
|
|
|
r->top = clipRect->top;
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
2004-01-09 07:53:08 +00:00
|
|
|
if (r->left < clipRect->left) {
|
|
|
|
src -= (r->left - clipRect->left);
|
|
|
|
r->left = clipRect->left;
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
2004-01-09 07:53:08 +00:00
|
|
|
if (r->bottom > clipRect->bottom)
|
|
|
|
r->bottom = clipRect->bottom;
|
|
|
|
if (r->right > clipRect->right)
|
|
|
|
r->right = clipRect->right;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
byte *dst = _buffer + r->top * _screenWide + r->left;
|
2004-07-26 16:41:57 +00:00
|
|
|
int i;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2003-08-28 06:36:15 +00:00
|
|
|
if (s->transparent) {
|
|
|
|
for (i = 0; i < r->bottom - r->top; i++) {
|
2004-07-26 16:41:57 +00:00
|
|
|
for (int j = 0; j < r->right - r->left; j++) {
|
2003-08-28 06:36:15 +00:00
|
|
|
if (src[j])
|
|
|
|
dst[j] = src[j];
|
|
|
|
}
|
|
|
|
src += BLOCKWIDTH;
|
2003-10-15 06:40:31 +00:00
|
|
|
dst += _screenWide;
|
2003-08-28 06:36:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < r->bottom - r->top; i++) {
|
|
|
|
memcpy(dst, src, r->right - r->left);
|
|
|
|
src += BLOCKWIDTH;
|
2003-10-15 06:40:31 +00:00
|
|
|
dst += _screenWide;
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
|
|
|
}
|
2003-08-19 08:47:09 +00:00
|
|
|
}
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
// There are two different separate functions for scaling the image - one fast
|
|
|
|
// and one good. Or at least that's the theory. I'm sure there are better ways
|
|
|
|
// to scale an image than this. The latter is used at the highest graphics
|
|
|
|
// quality setting. Note that the "good" scaler takes an extra parameter, a
|
|
|
|
// pointer to the area of the screen where the sprite will be drawn.
|
2003-08-20 21:17:23 +00:00
|
|
|
//
|
2004-06-06 15:40:31 +00:00
|
|
|
// This code isn't quite like the original DrawSprite(), but should be close
|
|
|
|
// enough.
|
2003-08-20 21:17:23 +00:00
|
|
|
|
2005-02-19 14:02:16 +00:00
|
|
|
void Screen::scaleImageFast(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight) {
|
2004-06-06 15:40:31 +00:00
|
|
|
int x, y;
|
2003-08-20 21:17:23 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
for (x = 0; x < dstWidth; x++)
|
|
|
|
_xScale[x] = (x * srcWidth) / dstWidth;
|
2003-08-20 21:17:23 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
for (y = 0; y < dstHeight; y++)
|
|
|
|
_yScale[y] = (y * srcHeight) / dstHeight;
|
2003-08-20 21:17:23 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
for (y = 0; y < dstHeight; y++) {
|
|
|
|
for (x = 0; x < dstWidth; x++) {
|
|
|
|
dst[x] = src[_yScale[y] * srcPitch + _xScale[x]];
|
2003-08-20 21:17:23 +00:00
|
|
|
}
|
2004-06-06 15:40:31 +00:00
|
|
|
dst += dstPitch;
|
2003-08-20 21:17:23 +00:00
|
|
|
}
|
2004-06-06 15:40:31 +00:00
|
|
|
}
|
2003-08-20 21:17:23 +00:00
|
|
|
|
2005-02-19 14:02:16 +00:00
|
|
|
void Screen::scaleImageGood(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight, byte *backbuf) {
|
2004-06-06 15:40:31 +00:00
|
|
|
for (int y = 0; y < dstHeight; y++) {
|
|
|
|
for (int x = 0; x < dstWidth; x++) {
|
|
|
|
uint8 c1, c2, c3, c4;
|
2003-08-27 07:17:12 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
uint32 xPos = (x * srcWidth) / dstWidth;
|
|
|
|
uint32 yPos = (y * srcHeight) / dstHeight;
|
|
|
|
uint32 xFrac = dstWidth - (x * srcWidth) % dstWidth;
|
|
|
|
uint32 yFrac = dstHeight - (y * srcHeight) % dstHeight;
|
2003-08-27 07:17:12 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
byte *srcPtr = src + yPos * srcPitch + xPos;
|
|
|
|
byte *backPtr = backbuf + y * _screenWide + x;
|
2003-08-27 07:17:12 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
bool transparent = true;
|
2003-08-27 07:17:12 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
if (*srcPtr) {
|
|
|
|
c1 = *srcPtr;
|
|
|
|
transparent = false;
|
|
|
|
} else
|
|
|
|
c1 = *backPtr;
|
2003-08-27 07:17:12 +00:00
|
|
|
|
2004-06-06 15:40:31 +00:00
|
|
|
if (x < dstWidth - 1) {
|
|
|
|
if (*(srcPtr + 1)) {
|
|
|
|
c2 = *(srcPtr + 1);
|
|
|
|
transparent = false;
|
2003-08-27 07:17:12 +00:00
|
|
|
} else
|
2004-06-06 15:40:31 +00:00
|
|
|
c2 = *(backPtr + 1);
|
|
|
|
} else
|
|
|
|
c2 = c1;
|
|
|
|
|
|
|
|
if (y < dstHeight - 1) {
|
|
|
|
if (*(srcPtr + srcPitch)) {
|
|
|
|
c3 = *(srcPtr + srcPitch);
|
|
|
|
transparent = false;
|
2003-08-27 07:17:12 +00:00
|
|
|
} else
|
2004-06-06 15:40:31 +00:00
|
|
|
c3 = *(backPtr + _screenWide);
|
|
|
|
} else
|
|
|
|
c3 = c1;
|
|
|
|
|
|
|
|
if (x < dstWidth - 1 && y < dstHeight - 1) {
|
|
|
|
if (*(srcPtr + srcPitch + 1)) {
|
|
|
|
c4 = *(srcPtr + srcPitch + 1);
|
|
|
|
transparent = false;
|
|
|
|
} else
|
|
|
|
c4 = *(backPtr + _screenWide + 1);
|
|
|
|
} else
|
|
|
|
c4 = c3;
|
|
|
|
|
|
|
|
if (!transparent) {
|
2004-06-09 06:33:29 +00:00
|
|
|
uint32 r1 = _palette[c1 * 4 + 0];
|
|
|
|
uint32 g1 = _palette[c1 * 4 + 1];
|
|
|
|
uint32 b1 = _palette[c1 * 4 + 2];
|
2004-06-06 15:40:31 +00:00
|
|
|
|
2004-06-09 06:33:29 +00:00
|
|
|
uint32 r2 = _palette[c2 * 4 + 0];
|
|
|
|
uint32 g2 = _palette[c2 * 4 + 1];
|
|
|
|
uint32 b2 = _palette[c2 * 4 + 2];
|
2004-06-06 15:40:31 +00:00
|
|
|
|
2004-06-09 06:33:29 +00:00
|
|
|
uint32 r3 = _palette[c3 * 4 + 0];
|
|
|
|
uint32 g3 = _palette[c3 * 4 + 1];
|
|
|
|
uint32 b3 = _palette[c3 * 4 + 2];
|
2004-06-06 15:40:31 +00:00
|
|
|
|
2004-06-09 06:33:29 +00:00
|
|
|
uint32 r4 = _palette[c4 * 4 + 0];
|
|
|
|
uint32 g4 = _palette[c4 * 4 + 1];
|
|
|
|
uint32 b4 = _palette[c4 * 4 + 2];
|
2004-06-06 15:40:31 +00:00
|
|
|
|
|
|
|
uint32 r5 = (r1 * xFrac + r2 * (dstWidth - xFrac)) / dstWidth;
|
|
|
|
uint32 g5 = (g1 * xFrac + g2 * (dstWidth - xFrac)) / dstWidth;
|
|
|
|
uint32 b5 = (b1 * xFrac + b2 * (dstWidth - xFrac)) / dstWidth;
|
|
|
|
|
|
|
|
uint32 r6 = (r3 * xFrac + r4 * (dstWidth - xFrac)) / dstWidth;
|
|
|
|
uint32 g6 = (g3 * xFrac + g4 * (dstWidth - xFrac)) / dstWidth;
|
|
|
|
uint32 b6 = (b3 * xFrac + b4 * (dstWidth - xFrac)) / dstWidth;
|
|
|
|
|
|
|
|
uint32 r = (r5 * yFrac + r6 * (dstHeight - yFrac)) / dstHeight;
|
|
|
|
uint32 g = (g5 * yFrac + g6 * (dstHeight - yFrac)) / dstHeight;
|
|
|
|
uint32 b = (b5 * yFrac + b6 * (dstHeight - yFrac)) / dstHeight;
|
|
|
|
|
|
|
|
dst[y * dstWidth + x] = quickMatch(r, g, b);
|
|
|
|
} else
|
|
|
|
dst[y * dstWidth + x] = 0;
|
2003-08-27 07:17:12 +00:00
|
|
|
}
|
|
|
|
}
|
2003-08-20 21:17:23 +00:00
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* Plots a point relative to the top left corner of the screen. This is only
|
|
|
|
* used for debugging.
|
|
|
|
* @param x x-coordinate of the point
|
|
|
|
* @param y y-coordinate of the point
|
|
|
|
* @param colour colour of the point
|
|
|
|
*/
|
|
|
|
|
2005-04-20 14:45:23 +00:00
|
|
|
void Screen::plotPoint(int x, int y, uint8 colour) {
|
2004-07-26 16:41:57 +00:00
|
|
|
byte *buf = _buffer + MENUDEEP * RENDERWIDE;
|
|
|
|
|
|
|
|
x -= _scrollX;
|
|
|
|
y -= _scrollY;
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
if (x >= 0 && x < RENDERWIDE && y >= 0 && y < RENDERDEEP) {
|
|
|
|
buf[y * RENDERWIDE + x] = colour;
|
|
|
|
markAsDirty(x, y + MENUDEEP, x, y + MENUDEEP);
|
2004-05-09 13:24:07 +00:00
|
|
|
}
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2005-04-20 14:45:23 +00:00
|
|
|
static void plot(int x, int y, int colour, void *data) {
|
2005-05-12 13:12:15 +00:00
|
|
|
Screen *screen = (Screen *)data;
|
2005-04-20 14:45:23 +00:00
|
|
|
screen->plotPoint(x, y, (uint8) colour);
|
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* Draws a line from one point to another. This is only used for debugging.
|
|
|
|
* @param x0 x-coordinate of the start point
|
|
|
|
* @param y0 y-coordinate of the start point
|
|
|
|
* @param x1 x-coordinate of the end point
|
|
|
|
* @param y1 y-coordinate of the end point
|
|
|
|
* @param colour colour of the line
|
|
|
|
*/
|
|
|
|
|
2005-04-20 14:45:23 +00:00
|
|
|
void Screen::drawLine(int x0, int y0, int x1, int y1, uint8 colour) {
|
2005-04-27 20:29:19 +00:00
|
|
|
Graphics::drawLine(x0, y0, x1, y1, colour, &plot, this);
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* This function tells the driver the size of the background screen for the
|
|
|
|
* current location.
|
|
|
|
* @param w width of the current location
|
|
|
|
* @param h height of the current location
|
|
|
|
*/
|
|
|
|
|
2005-02-19 14:02:16 +00:00
|
|
|
void Screen::setLocationMetrics(uint16 w, uint16 h) {
|
2003-10-15 06:40:31 +00:00
|
|
|
_locationWide = w;
|
|
|
|
_locationDeep = h;
|
2004-01-04 15:11:30 +00:00
|
|
|
setNeedFullRedraw();
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* Draws a parallax layer at the current position determined by the scroll. A
|
|
|
|
* parallax can be either foreground, background or the main screen.
|
|
|
|
*/
|
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
void Screen::renderParallax(byte *ptr, int16 l) {
|
|
|
|
Parallax p;
|
2003-08-17 14:07:16 +00:00
|
|
|
int16 x, y;
|
2003-10-02 17:43:02 +00:00
|
|
|
Common::Rect r;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
p.read(ptr);
|
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
if (_locationWide == _screenWide)
|
2003-08-17 14:07:16 +00:00
|
|
|
x = 0;
|
|
|
|
else
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
x = ((int32)((p.w - _screenWide) * _scrollX) / (int32)(_locationWide - _screenWide));
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
if (_locationDeep == _screenDeep - MENUDEEP * 2)
|
2003-08-17 14:07:16 +00:00
|
|
|
y = 0;
|
|
|
|
else
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
y = ((int32)((p.h - (_screenDeep - MENUDEEP * 2)) * _scrollY) / (int32)(_locationDeep - (_screenDeep - MENUDEEP * 2)));
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2004-01-09 07:53:08 +00:00
|
|
|
Common::Rect clipRect;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
|
|
|
// Leave enough space for the top and bottom menues
|
|
|
|
|
2004-01-09 07:53:08 +00:00
|
|
|
clipRect.left = 0;
|
|
|
|
clipRect.right = _screenWide;
|
|
|
|
clipRect.top = MENUDEEP;
|
|
|
|
clipRect.bottom = _screenDeep - MENUDEEP;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
for (int j = 0; j < _yBlocks[l]; j++) {
|
|
|
|
for (int i = 0; i < _xBlocks[l]; i++) {
|
|
|
|
if (_blockSurfaces[l][i + j * _xBlocks[l]]) {
|
2003-08-17 14:07:16 +00:00
|
|
|
r.left = i * BLOCKWIDTH - x;
|
|
|
|
r.right = r.left + BLOCKWIDTH;
|
2004-07-26 16:41:57 +00:00
|
|
|
r.top = j * BLOCKHEIGHT - y + MENUDEEP;
|
2003-08-17 14:07:16 +00:00
|
|
|
r.bottom = r.top + BLOCKHEIGHT;
|
2004-01-09 07:53:08 +00:00
|
|
|
blitBlockSurface(_blockSurfaces[l][i + j * _xBlocks[l]], &r, &clipRect);
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
_parallaxScrollX = _scrollX - x;
|
|
|
|
_parallaxScrollY = _scrollY - y;
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2003-08-29 06:42:34 +00:00
|
|
|
// Uncomment this when benchmarking the drawing routines.
|
|
|
|
#define LIMIT_FRAME_RATE
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* Initialises the timers before the render loop is entered.
|
|
|
|
*/
|
|
|
|
|
2005-05-02 05:41:01 +00:00
|
|
|
void Screen::initialiseRenderCycle() {
|
2004-09-28 20:19:37 +00:00
|
|
|
_initialTime = _vm->_system->getMillis();
|
2003-10-15 06:40:31 +00:00
|
|
|
_totalTime = _initialTime + MILLISECSPERCYCLE;
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* This function should be called when the game engine is ready to start the
|
|
|
|
* render cycle.
|
|
|
|
*/
|
|
|
|
|
2005-05-02 05:41:01 +00:00
|
|
|
void Screen::startRenderCycle() {
|
2003-10-15 06:40:31 +00:00
|
|
|
_scrollXOld = _scrollX;
|
|
|
|
_scrollYOld = _scrollY;
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2004-09-28 20:19:37 +00:00
|
|
|
_startTime = _vm->_system->getMillis();
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
if (_startTime + _renderAverageTime >= _totalTime) {
|
|
|
|
_scrollX = _scrollXTarget;
|
|
|
|
_scrollY = _scrollYTarget;
|
|
|
|
_renderTooSlow = true;
|
2003-08-20 21:17:23 +00:00
|
|
|
} else {
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
_scrollX = (int16)(_scrollXOld + ((_scrollXTarget - _scrollXOld) * (_startTime - _initialTime + _renderAverageTime)) / (_totalTime - _initialTime));
|
|
|
|
_scrollY = (int16)(_scrollYOld + ((_scrollYTarget - _scrollYOld) * (_startTime - _initialTime + _renderAverageTime)) / (_totalTime - _initialTime));
|
2003-10-15 06:40:31 +00:00
|
|
|
_renderTooSlow = false;
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2004-01-04 15:11:30 +00:00
|
|
|
if (_scrollXOld != _scrollX || _scrollYOld != _scrollY)
|
|
|
|
setNeedFullRedraw();
|
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
_framesPerGameCycle = 0;
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* This function should be called at the end of the render cycle.
|
2005-07-30 21:11:48 +00:00
|
|
|
* @return true if the render cycle is to be terminated,
|
2004-03-15 00:55:44 +00:00
|
|
|
* or false if it should continue
|
2003-09-28 14:13:57 +00:00
|
|
|
*/
|
|
|
|
|
2005-05-02 05:41:01 +00:00
|
|
|
bool Screen::endRenderCycle() {
|
2003-10-15 06:40:31 +00:00
|
|
|
static int32 renderTimeLog[4] = { 60, 60, 60, 60 };
|
|
|
|
static int32 renderCountIndex = 0;
|
2003-07-28 01:47:41 +00:00
|
|
|
int32 time;
|
|
|
|
|
2004-09-28 20:19:37 +00:00
|
|
|
time = _vm->_system->getMillis();
|
2003-10-15 06:40:31 +00:00
|
|
|
renderTimeLog[renderCountIndex] = time - _startTime;
|
|
|
|
_startTime = time;
|
|
|
|
_renderAverageTime = (renderTimeLog[0] + renderTimeLog[1] + renderTimeLog[2] + renderTimeLog[3]) >> 2;
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
_framesPerGameCycle++;
|
2003-07-28 01:47:41 +00:00
|
|
|
|
|
|
|
if (++renderCountIndex == RENDERAVERAGETOTAL)
|
|
|
|
renderCountIndex = 0;
|
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
if (_renderTooSlow) {
|
|
|
|
initialiseRenderCycle();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_startTime + _renderAverageTime >= _totalTime) {
|
|
|
|
_totalTime += MILLISECSPERCYCLE;
|
|
|
|
_initialTime = time;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2003-08-29 06:42:34 +00:00
|
|
|
#ifdef LIMIT_FRAME_RATE
|
2003-10-15 06:40:31 +00:00
|
|
|
if (_scrollXTarget == _scrollX && _scrollYTarget == _scrollY) {
|
2003-08-29 06:42:34 +00:00
|
|
|
// If we have already reached the scroll target sleep for the
|
|
|
|
// rest of the render cycle.
|
2003-11-16 14:18:29 +00:00
|
|
|
_vm->sleepUntil(_totalTime);
|
2004-09-28 20:19:37 +00:00
|
|
|
_initialTime = _vm->_system->getMillis();
|
2003-10-15 06:40:31 +00:00
|
|
|
_totalTime += MILLISECSPERCYCLE;
|
|
|
|
return true;
|
|
|
|
}
|
2003-08-29 06:42:34 +00:00
|
|
|
#endif
|
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
// This is an attempt to ensure that we always reach the scroll target.
|
|
|
|
// Otherwise the game frequently tries to pump out new interpolation
|
|
|
|
// frames without ever getting anywhere.
|
2003-08-29 06:42:34 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
if (ABS(_scrollX - _scrollXTarget) <= 1 && ABS(_scrollY - _scrollYTarget) <= 1) {
|
|
|
|
_scrollX = _scrollXTarget;
|
|
|
|
_scrollY = _scrollYTarget;
|
|
|
|
} else {
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
_scrollX = (int16)(_scrollXOld + ((_scrollXTarget - _scrollXOld) * (_startTime - _initialTime + _renderAverageTime)) / (_totalTime - _initialTime));
|
|
|
|
_scrollY = (int16)(_scrollYOld + ((_scrollYTarget - _scrollYOld) * (_startTime - _initialTime + _renderAverageTime)) / (_totalTime - _initialTime));
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2004-01-04 15:11:30 +00:00
|
|
|
if (_scrollX != _scrollXOld || _scrollY != _scrollYOld)
|
|
|
|
setNeedFullRedraw();
|
|
|
|
|
2004-01-14 10:58:09 +00:00
|
|
|
#ifdef LIMIT_FRAME_RATE
|
|
|
|
// Give the other threads some breathing space. This apparently helps
|
|
|
|
// against bug #875683, though I was never able to reproduce it for
|
|
|
|
// myself.
|
2004-09-28 20:19:37 +00:00
|
|
|
_vm->_system->delayMillis(10);
|
2004-01-14 10:58:09 +00:00
|
|
|
#endif
|
2004-01-13 10:27:13 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
return false;
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2004-04-07 12:31:32 +00:00
|
|
|
/**
|
|
|
|
* Reset scrolling stuff. This function is called from initBackground()
|
|
|
|
*/
|
|
|
|
|
2005-05-02 05:41:01 +00:00
|
|
|
void Screen::resetRenderEngine() {
|
2004-04-07 12:31:32 +00:00
|
|
|
_parallaxScrollX = 0;
|
|
|
|
_parallaxScrollY = 0;
|
|
|
|
_scrollX = 0;
|
|
|
|
_scrollY = 0;
|
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* This function should be called five times with either the parallax layer
|
|
|
|
* or a NULL pointer in order of background parallax to foreground parallax.
|
|
|
|
*/
|
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
int32 Screen::initialiseBackgroundLayer(byte *parallax) {
|
|
|
|
Parallax p;
|
2003-08-17 14:07:16 +00:00
|
|
|
uint16 i, j, k;
|
2004-04-23 07:02:11 +00:00
|
|
|
byte *data;
|
|
|
|
byte *dst;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
debug(2, "initialiseBackgroundLayer");
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
assert(_layer < MAXLAYERS);
|
2003-08-17 14:07:16 +00:00
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
if (!parallax) {
|
2003-10-15 06:40:31 +00:00
|
|
|
_layer++;
|
2003-08-17 14:07:16 +00:00
|
|
|
return RD_OK;
|
|
|
|
}
|
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
p.read(parallax);
|
|
|
|
|
|
|
|
_xBlocks[_layer] = (p.w + BLOCKWIDTH - 1) / BLOCKWIDTH;
|
|
|
|
_yBlocks[_layer] = (p.h + BLOCKHEIGHT - 1) / BLOCKHEIGHT;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2005-05-12 13:12:15 +00:00
|
|
|
_blockSurfaces[_layer] = (BlockSurface **)calloc(_xBlocks[_layer] * _yBlocks[_layer], sizeof(BlockSurface *));
|
2003-10-15 06:40:31 +00:00
|
|
|
if (!_blockSurfaces[_layer])
|
2003-08-17 14:07:16 +00:00
|
|
|
return RDERR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
// Decode the parallax layer into a large chunk of memory
|
|
|
|
|
2005-05-12 13:12:15 +00:00
|
|
|
byte *memchunk = (byte *)calloc(_xBlocks[_layer] * _yBlocks[_layer], BLOCKWIDTH * BLOCKHEIGHT);
|
2003-08-17 14:07:16 +00:00
|
|
|
if (!memchunk)
|
|
|
|
return RDERR_OUTOFMEMORY;
|
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
for (i = 0; i < p.h; i++) {
|
|
|
|
uint32 p_offset = READ_LE_UINT32(parallax + Parallax::size() + 4 * i);
|
|
|
|
|
|
|
|
if (!p_offset)
|
2003-08-17 14:07:16 +00:00
|
|
|
continue;
|
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
byte *pLine = parallax + p_offset;
|
2004-07-26 16:41:57 +00:00
|
|
|
uint16 packets = READ_LE_UINT16(pLine);
|
|
|
|
uint16 offset = READ_LE_UINT16(pLine + 2);
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
data = pLine + 4;
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
dst = memchunk + i * p.w + offset;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
if (!packets) {
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
memcpy(dst, data, p.w);
|
2003-08-17 14:07:16 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
bool zeros = false;
|
|
|
|
|
|
|
|
for (j = 0; j < packets; j++) {
|
2003-08-17 14:07:16 +00:00
|
|
|
if (zeros) {
|
|
|
|
dst += *data;
|
2004-07-26 16:41:57 +00:00
|
|
|
offset += *data;
|
2003-08-17 14:07:16 +00:00
|
|
|
data++;
|
2004-07-26 16:41:57 +00:00
|
|
|
zeros = false;
|
|
|
|
} else if (!*data) {
|
2003-08-17 14:07:16 +00:00
|
|
|
data++;
|
2004-07-26 16:41:57 +00:00
|
|
|
zeros = true;
|
2003-08-17 14:07:16 +00:00
|
|
|
} else {
|
2004-07-26 16:41:57 +00:00
|
|
|
uint16 count = *data++;
|
2003-08-17 14:07:16 +00:00
|
|
|
memcpy(dst, data, count);
|
|
|
|
data += count;
|
|
|
|
dst += count;
|
2004-07-26 16:41:57 +00:00
|
|
|
offset += count;
|
|
|
|
zeros = true;
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
// The large memory chunk is now divided into a number of smaller
|
|
|
|
// surfaces. For most parallax layers, we'll end up using less memory
|
|
|
|
// this way, and it will be faster to draw since completely transparent
|
|
|
|
// surfaces are discarded.
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
for (i = 0; i < _xBlocks[_layer] * _yBlocks[_layer]; i++) {
|
2003-08-17 14:07:16 +00:00
|
|
|
bool block_has_data = false;
|
2003-08-28 06:36:15 +00:00
|
|
|
bool block_is_transparent = false;
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
int x = BLOCKWIDTH * (i % _xBlocks[_layer]);
|
|
|
|
int y = BLOCKHEIGHT * (i / _xBlocks[_layer]);
|
2003-08-17 14:07:16 +00:00
|
|
|
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
data = memchunk + p.w * y + x;
|
2003-12-08 07:30:22 +00:00
|
|
|
|
2003-08-17 14:07:16 +00:00
|
|
|
for (j = 0; j < BLOCKHEIGHT; j++) {
|
2003-08-28 06:36:15 +00:00
|
|
|
for (k = 0; k < BLOCKWIDTH; k++) {
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
if (x + k < p.w && y + j < p.h) {
|
|
|
|
if (data[j * p.w + k])
|
2004-07-26 16:41:57 +00:00
|
|
|
block_has_data = true;
|
|
|
|
else
|
|
|
|
block_is_transparent = true;
|
|
|
|
}
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only assign a surface to the block if it contains data.
|
|
|
|
|
|
|
|
if (block_has_data) {
|
2005-05-12 13:12:15 +00:00
|
|
|
_blockSurfaces[_layer][i] = (BlockSurface *)malloc(sizeof(BlockSurface));
|
2003-08-17 14:07:16 +00:00
|
|
|
|
|
|
|
// Copy the data into the surfaces.
|
2003-10-15 06:40:31 +00:00
|
|
|
dst = _blockSurfaces[_layer][i]->data;
|
2003-08-17 14:07:16 +00:00
|
|
|
for (j = 0; j < BLOCKHEIGHT; j++) {
|
|
|
|
memcpy(dst, data, BLOCKWIDTH);
|
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.
To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.
If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.
If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.
Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.
On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.
Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.
svn-id: r19366
2005-10-29 21:24:54 +00:00
|
|
|
data += p.w;
|
2003-08-17 14:07:16 +00:00
|
|
|
dst += BLOCKWIDTH;
|
|
|
|
}
|
2003-08-28 06:36:15 +00:00
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
_blockSurfaces[_layer][i]->transparent = block_is_transparent;
|
2003-08-28 06:36:15 +00:00
|
|
|
|
2003-08-17 14:07:16 +00:00
|
|
|
} else
|
2003-10-15 06:40:31 +00:00
|
|
|
_blockSurfaces[_layer][i] = NULL;
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
2003-09-28 16:27:51 +00:00
|
|
|
|
2003-08-17 14:07:16 +00:00
|
|
|
free(memchunk);
|
2003-10-15 06:40:31 +00:00
|
|
|
_layer++;
|
2003-07-28 01:47:41 +00:00
|
|
|
|
2003-09-28 16:27:51 +00:00
|
|
|
return RD_OK;
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
|
|
|
|
2003-09-28 14:13:57 +00:00
|
|
|
/**
|
|
|
|
* Should be called once after leaving the room to free up memory.
|
|
|
|
*/
|
|
|
|
|
2005-05-02 05:41:01 +00:00
|
|
|
void Screen::closeBackgroundLayer() {
|
2003-08-20 21:17:23 +00:00
|
|
|
debug(2, "CloseBackgroundLayer");
|
2003-08-17 14:07:16 +00:00
|
|
|
|
2004-07-26 16:41:57 +00:00
|
|
|
for (int i = 0; i < MAXLAYERS; i++) {
|
|
|
|
if (_blockSurfaces[i]) {
|
|
|
|
for (int j = 0; j < _xBlocks[i] * _yBlocks[i]; j++)
|
|
|
|
if (_blockSurfaces[i][j])
|
|
|
|
free(_blockSurfaces[i][j]);
|
|
|
|
free(_blockSurfaces[i]);
|
|
|
|
_blockSurfaces[i] = NULL;
|
2003-08-17 14:07:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-15 06:40:31 +00:00
|
|
|
_layer = 0;
|
2003-07-28 01:47:41 +00:00
|
|
|
}
|
2003-10-04 00:52:27 +00:00
|
|
|
|
|
|
|
} // End of namespace Sword2
|