Files
2026-02-02 04:50:13 +01:00

1400 lines
40 KiB
C++

/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/nuvie/core/nuvie_defs.h"
#include "ultima/nuvie/misc/u6_misc.h"
#include "ultima/nuvie/conf/configuration.h"
#include "ultima/nuvie/screen/surface.h"
#include "ultima/nuvie/screen/screen.h"
#include "ultima/nuvie/gui/widgets/map_window.h"
#include "ultima/nuvie/gui/widgets/background.h"
#include "common/system.h"
#include "engines/util.h"
namespace Ultima {
namespace Nuvie {
#define sqr(a) ((a)*(a))
//Ultima 6 light globe sizes.
static const int NUM_GLOBES = 5;
static const int SHADING_BORDER = 2; // should be the same as MapWindow's TMP_MAP_BORDER
static const sint32 globeradius[] = { 36, 112, 148, 192, 448 };
static const sint32 globeradius_2[] = { 18, 56, 74, 96, 224 };
Screen::Screen(const Configuration *cfg) : config(cfg), _rawSurface(nullptr),
_renderSurface(nullptr), shading_data(nullptr), is_no_darkness(false),
non_square_pixels(false), shading_ambient(255), width(320), height(200) {
ARRAYCLEAR(shading_tile);
Std::string str_lighting_style;
config->value("config/general/lighting", str_lighting_style);
if (str_lighting_style == "none")
lighting_style = LightingNone;
else if (str_lighting_style == "smooth")
lighting_style = LightingSmooth;
else
lighting_style = LightingOriginal;
old_lighting_style = lighting_style;
memset(shading_globe, 0, sizeof(shading_globe));
}
Screen::~Screen() {
delete _renderSurface;
delete _rawSurface;
if (shading_data)
free(shading_data);
for (int i = 0; i < NUM_GLOBES; i++) {
if (shading_globe[i])
free(shading_globe[i]);
}
}
bool Screen::init() {
int new_width, new_height;
config->value("config/video/screen_width", new_width, 320);
config->value("config/video/screen_height", new_height, 200);
if (new_width < 320)
new_width = 320;
if (new_height < 200)
new_height = 200;
width = (uint16)new_width;
height = (uint16)new_height;
config->value("config/video/non_square_pixels", non_square_pixels, false);
set_screen_mode();
return true;
}
bool Screen::toggle_darkness_cheat() {
is_no_darkness = !is_no_darkness;
if (is_no_darkness) {
old_lighting_style = lighting_style;
lighting_style = LightingNone;
} else
lighting_style = old_lighting_style;
return is_no_darkness;
}
bool Screen::set_palette(const uint8 *p) {
if (_renderSurface == nullptr || p == nullptr)
return false;
for (int i = 0; i < 256; ++i) {
uint32 r = p[i * 3];
uint32 g = p[i * 3 + 1];
uint32 b = p[i * 3 + 2];
uint32 c = ((r >> RenderSurface::Rloss) << RenderSurface::Rshift) | ((g >> RenderSurface::Gloss) << RenderSurface::Gshift) | ((b >> RenderSurface::Bloss) << RenderSurface::Bshift);
_renderSurface->colour32[i] = c;
}
return true;
}
bool Screen::set_palette_entry(uint8 idx, uint8 r, uint8 g, uint8 b) {
if (_renderSurface == nullptr)
return false;
uint32 c = ((((uint32)r) >> RenderSurface::Rloss) << RenderSurface::Rshift) | ((((uint32)g) >> RenderSurface::Gloss) << RenderSurface::Gshift) | ((((uint32)b) >> RenderSurface::Bloss) << RenderSurface::Bshift);
_renderSurface->colour32[idx] = c;
return true;
}
bool Screen::rotate_palette(uint8 pos, uint8 length) {
uint32 tmp_colour = _renderSurface->colour32[pos + length - 1];
for (int i = length - 1; i > 0; i--)
_renderSurface->colour32[pos + i] = _renderSurface->colour32[pos + i - 1];
_renderSurface->colour32[pos] = tmp_colour;
return true;
}
bool Screen::clear(sint16 x, sint16 y, sint16 w, sint16 h, Common::Rect *clip_rect) {
uint8 *pixels = (uint8 *)_renderSurface->pixels;
if (x >= width || y >= height)
return false;
if (x < 0) {
if (x + w <= 0)
return false;
else
w += x;
x = 0;
}
if (y < 0) {
if (y + h <= 0)
return false;
else
h += y;
y = 0;
}
if (x + w >= width)
w = width - x;
if (y + h >= height)
h = height - y;
if (clip_rect) {
uint16 x1 = x;
uint16 y1 = y;
if (x < clip_rect->left)
x = clip_rect->left;
if (y < clip_rect->top)
y = clip_rect->top;
if (x1 + w > clip_rect->left + clip_rect->width()) {
w -= (x1 + w) - (clip_rect->left + clip_rect->width());
if (w <= 0)
return false;
}
if (y1 + h > clip_rect->top + clip_rect->height()) {
h -= (y1 + h) - (clip_rect->top + clip_rect->height());
if (h <= 0)
return false;
}
}
pixels += y * _renderSurface->pitch + (x * _renderSurface->bytes_per_pixel);
for (uint16 i = 0; i < h; i++) {
memset(pixels, 0, w * _renderSurface->bytes_per_pixel);
pixels += _renderSurface->pitch;
}
return true;
}
bool Screen::fill(uint8 colour_num, uint16 x, uint16 y, sint16 w, sint16 h) {
if (x >= _renderSurface->w || y >= _renderSurface->h) {
return true;
}
if ((uint32)(y + h) > _renderSurface->h) {
h = _renderSurface->h - y;
}
if ((uint32)(x + w) > _renderSurface->w) {
w = _renderSurface->w - x;
}
if (_renderSurface->bits_per_pixel == 16)
return fill16(colour_num, x, y, w, h);
return fill32(colour_num, x, y, w, h);
}
bool Screen::fill16(uint8 colour_num, uint16 x, uint16 y, sint16 w, sint16 h) {
uint16 *pixels = (uint16 *)_renderSurface->pixels;
pixels += y * _renderSurface->w + x;
for (uint16 i = 0; i < h; i++) {
for (uint16 j = 0; j < w; j++)
pixels[j] = (uint16)_renderSurface->colour32[colour_num];
pixels += _renderSurface->w;
}
return true;
}
bool Screen::fill32(uint8 colour_num, uint16 x, uint16 y, sint16 w, sint16 h) {
uint32 *pixels = (uint32 *)_renderSurface->pixels;
pixels += y * _renderSurface->w + x;
for (uint16 i = 0; i < h; i++) {
for (uint16 j = 0; j < w; j++)
pixels[j] = _renderSurface->colour32[colour_num];
pixels += _renderSurface->w;
}
return true;
}
void Screen::fade(uint16 dest_x, uint16 dest_y, uint16 src_w, uint16 src_h, uint8 opacity, uint8 fade_bg_color) {
if (_renderSurface->bits_per_pixel == 16)
fade16(dest_x, dest_y, src_w, src_h, opacity, fade_bg_color);
else
fade32(dest_x, dest_y, src_w, src_h, opacity, fade_bg_color);
}
void Screen::fade16(uint16 dest_x, uint16 dest_y, uint16 src_w, uint16 src_h, uint8 opacity, uint8 fade_bg_color) {
uint16 bg = (uint16)_renderSurface->colour32[fade_bg_color];
uint16 *pixels = (uint16 *)_renderSurface->pixels;
pixels += dest_y * _renderSurface->w + dest_x;
for (uint16 i = 0; i < src_h; i++) {
for (uint16 j = 0; j < src_w; j++) {
pixels[j] = blendpixel16(bg, pixels[j], opacity);
}
pixels += _renderSurface->w; //_renderSurface->pitch;
}
return;
}
void Screen::fade32(uint16 dest_x, uint16 dest_y, uint16 src_w, uint16 src_h, uint8 opacity, uint8 fade_bg_color) {
uint32 bg = _renderSurface->colour32[fade_bg_color];
uint32 *pixels = (uint32 *)_renderSurface->pixels;
pixels += dest_y * _renderSurface->w + dest_x;
for (uint16 i = 0; i < src_h; i++) {
for (uint16 j = 0; j < src_w; j++) {
pixels[j] = blendpixel32(bg, pixels[j], opacity);
}
pixels += _renderSurface->w; //_renderSurface->pitch;
}
return;
}
void Screen::stipple_8bit(uint8 color_num) {
stipple_8bit(color_num, 0, 0, _renderSurface->w, _renderSurface->h);
}
void Screen::stipple_8bit(uint8 color_num, uint16 x, uint16 y, uint16 w, uint16 h) {
uint32 i, j;
if (x >= _renderSurface->w || y >= _renderSurface->h) {
return;
}
if ((uint32)(y + h) > _renderSurface->h) {
h = _renderSurface->h - y;
}
if ((uint32)(x + w) > _renderSurface->w) {
w = _renderSurface->w - x;
}
if (_renderSurface->bits_per_pixel == 16) {
uint16 color = (uint16)_renderSurface->colour32[color_num];
uint16 *pixels = (uint16 *)_renderSurface->pixels;
pixels += y * _renderSurface->w + x;
for (i = y; i < (uint32)(y + h); i++) {
for (j = x; j < (uint32)(x + w); j += 2) {
*pixels = color;
pixels += 2;
}
pixels += (_renderSurface->w - j) + x;
if (i % 2) {
pixels--;
} else {
pixels++;
}
}
} else {
uint32 color = _renderSurface->colour32[color_num];
uint32 *pixels = (uint32 *)_renderSurface->pixels;
pixels += y * _renderSurface->w + x;
for (i = 0; i < h; i++) {
for (j = x; j < (uint32)(x + w); j += 2) {
*pixels = color;
pixels += 2;
}
pixels += (_renderSurface->w - j) + x;
if (i % 2) {
pixels--;
} else {
pixels++;
}
}
}
}
void Screen::put_pixel(uint8 colour_num, uint16 x, uint16 y) {
if (_renderSurface->bits_per_pixel == 16) {
uint16 *pixel = (uint16 *)_renderSurface->pixels + y * _renderSurface->w + x;
*pixel = (uint16)_renderSurface->colour32[colour_num];
} else {
uint32 *pixel = (uint32 *)_renderSurface->pixels + y * _renderSurface->w + x;
*pixel = (uint32)_renderSurface->colour32[colour_num];
}
}
Graphics::ManagedSurface *Screen::get_sdl_surface() {
if (_renderSurface)
return _renderSurface->get_sdl_surface();
return nullptr;
}
bool Screen::blit(int32 dest_x, int32 dest_y, const byte *src_buf, uint16 src_bpp,
uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans,
const Common::Rect *clip_rect, uint8 opacity) {
// clip to screen.
if (dest_x >= width || dest_y >= height)
return false;
if (dest_x < 0) {
if (dest_x + src_w <= 0)
return false;
else
src_w += dest_x;
src_buf += -dest_x;
dest_x = 0;
}
if (dest_y < 0) {
if (dest_y + src_h <= 0)
return false;
else
src_h += dest_y;
src_buf += src_pitch * -dest_y;
dest_y = 0;
}
if (dest_x + src_w >= width)
src_w = width - dest_x;
if (dest_y + src_h >= height)
src_h = height - dest_y;
//clip to rect if required.
if (clip_rect) {
uint16 src_x = 0;
uint16 src_y = 0;
if (dest_x + src_w < clip_rect->left || dest_y + src_h < clip_rect->top)
return false;
if (clip_rect->left > dest_x) {
src_x = clip_rect->left - dest_x;
src_w -= src_x;
dest_x = clip_rect->left;
}
if (clip_rect->top > dest_y) {
src_y = clip_rect->top - dest_y;
src_h -= src_y;
dest_y = clip_rect->top;
}
if (dest_x + src_w > clip_rect->left + clip_rect->width()) {
if (clip_rect->left + clip_rect->width() - dest_x <= 0)
return false;
src_w = clip_rect->left + clip_rect->width() - dest_x;
}
if (dest_y + src_h > clip_rect->top + clip_rect->height()) {
if (clip_rect->top + clip_rect->height() - dest_y <= 0)
return false;
src_h = clip_rect->top + clip_rect->height() - dest_y;
}
src_buf += src_y * src_pitch + src_x;
}
if (_renderSurface->bits_per_pixel == 16) {
if (opacity < 255)
return blit16WithOpacity(dest_x, dest_y, src_buf, src_bpp, src_w, src_h, src_pitch, trans, opacity);
return blit16(dest_x, dest_y, src_buf, src_bpp, src_w, src_h, src_pitch, trans);
}
if (opacity < 255)
return blit32WithOpacity(dest_x, dest_y, src_buf, src_bpp, src_w, src_h, src_pitch, trans, opacity);
return blit32(dest_x, dest_y, src_buf, src_bpp, src_w, src_h, src_pitch, trans);
}
inline uint16 Screen::blendpixel16(uint16 p, uint16 p1, uint8 opacity) {
return (((uint8)(((float)((p1 & _renderSurface->Rmask) >> _renderSurface->Rshift)) * (float)(opacity) / 255.0f) + (uint8)(((float)((p & _renderSurface->Rmask) >> _renderSurface->Rshift)) * (float)(255 - opacity) / 255.0f)) << _renderSurface->Rshift) | //R
(((uint8)(((float)((p1 & _renderSurface->Gmask) >> _renderSurface->Gshift)) * (float)(opacity) / 255.0f) + (uint8)(((float)((p & _renderSurface->Gmask) >> _renderSurface->Gshift)) * (float)(255 - opacity) / 255.0f)) << _renderSurface->Gshift) | //G
(((uint8)(((float)((p1 & _renderSurface->Bmask) >> _renderSurface->Bshift)) * (float)(opacity) / 255.0f) + (uint8)(((float)((p & _renderSurface->Bmask) >> _renderSurface->Bshift)) * (float)(255 - opacity) / 255.0f)) << _renderSurface->Bshift); //B
}
inline uint32 Screen::blendpixel32(uint32 p, uint32 p1, uint8 opacity) {
return (((uint8)(((float)((p1 & _renderSurface->Rmask) >> _renderSurface->Rshift)) * (float)(opacity) / 255.0f) + (uint8)(((float)((p & _renderSurface->Rmask) >> _renderSurface->Rshift)) * (float)(255 - opacity) / 255.0f)) << _renderSurface->Rshift) | //R
(((uint8)(((float)((p1 & _renderSurface->Gmask) >> _renderSurface->Gshift)) * (float)(opacity) / 255.0f) + (uint8)(((float)((p & _renderSurface->Gmask) >> _renderSurface->Gshift)) * (float)(255 - opacity) / 255.0f)) << _renderSurface->Gshift) | //G
(((uint8)(((float)((p1 & _renderSurface->Bmask) >> _renderSurface->Bshift)) * (float)(opacity) / 255.0f) + (uint8)(((float)((p & _renderSurface->Bmask) >> _renderSurface->Bshift)) * (float)(255 - opacity) / 255.0f)) << _renderSurface->Bshift); //B
}
inline bool Screen::blit16(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans) {
uint16 *pixels = (uint16 *)_renderSurface->pixels + dest_y * _renderSurface->w + dest_x;
if (trans) {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
if (src_buf[j] != 0xff)
pixels[j] = (uint16)_renderSurface->colour32[src_buf[j]];
}
src_buf += src_pitch;
pixels += _renderSurface->w; //pitch;
}
} else {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels[j] = (uint16)_renderSurface->colour32[src_buf[j]];
}
src_buf += src_pitch;
pixels += _renderSurface->w; //_renderSurface->pitch;
}
}
return true;
}
inline bool Screen::blit16WithOpacity(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans, uint8 opacity) {
uint16 *pixels = (uint16 *)_renderSurface->pixels + dest_y * _renderSurface->w + dest_x;
if (trans) {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
if (src_buf[j] != 0xff)
pixels[j] = blendpixel16(pixels[j], (uint16)_renderSurface->colour32[src_buf[j]], opacity);
}
src_buf += src_pitch;
pixels += _renderSurface->w; //pitch;
}
} else {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels[j] = blendpixel16(pixels[j], (uint16)_renderSurface->colour32[src_buf[j]], opacity);
}
src_buf += src_pitch;
pixels += _renderSurface->w; //_renderSurface->pitch;
}
}
return true;
}
bool Screen::blit32(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans) {
uint32 *pixels = (uint32 *)_renderSurface->pixels + dest_y * _renderSurface->w + dest_x;
if (trans) {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
if (src_buf[j] != 0xff)
pixels[j] = _renderSurface->colour32[src_buf[j]];
}
src_buf += src_pitch;
pixels += _renderSurface->w; //pitch;
}
} else {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels[j] = _renderSurface->colour32[src_buf[j]];
}
src_buf += src_pitch;
pixels += _renderSurface->w; //_renderSurface->pitch;
}
}
return true;
}
bool Screen::blit32WithOpacity(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans, uint8 opacity) {
uint32 *pixels = (uint32 *)_renderSurface->pixels + dest_y * _renderSurface->w + dest_x;
if (trans) {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
if (src_buf[j] != 0xff)
pixels[j] = blendpixel32(pixels[j], _renderSurface->colour32[src_buf[j]], opacity);
}
src_buf += src_pitch;
pixels += _renderSurface->w; //pitch;
}
} else {
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels[j] = blendpixel32(pixels[j], _renderSurface->colour32[src_buf[j]], opacity);
}
src_buf += src_pitch;
pixels += _renderSurface->w; //_renderSurface->pitch;
}
}
return true;
}
void Screen::blitbitmap(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_w, uint16 src_h, uint8 fg_color, uint8 bg_color) {
if (_renderSurface->bits_per_pixel == 16)
blitbitmap16(dest_x, dest_y, src_buf, src_w, src_h, fg_color, bg_color);
else
blitbitmap32(dest_x, dest_y, src_buf, src_w, src_h, fg_color, bg_color);
return;
}
void Screen::blitbitmap16(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_w, uint16 src_h, uint8 fg_color, uint8 bg_color) {
uint16 *pixels = (uint16 *)_renderSurface->pixels + dest_y * _renderSurface->w + dest_x;
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
if (src_buf[j])
pixels[j] = (uint16)_renderSurface->colour32[fg_color];
else
pixels[j] = (uint16)_renderSurface->colour32[bg_color];
}
src_buf += src_w;
pixels += _renderSurface->w; //_renderSurface->pitch;
}
return;
}
void Screen::blitbitmap32(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_w, uint16 src_h, uint8 fg_color, uint8 bg_color) {
uint32 *pixels = (uint32 *)_renderSurface->pixels + dest_y * _renderSurface->w + dest_x;
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
if (src_buf[j])
pixels[j] = _renderSurface->colour32[fg_color];
else
pixels[j] = _renderSurface->colour32[bg_color];
}
src_buf += src_w;
pixels += _renderSurface->w; //_renderSurface->pitch;
}
return;
}
//4 is pure-light
//0 is pitch-black
//Globe of r 1 is just a single tile of 2
static const char TileGlobe[][11 * 11] = {
{
// 1 - magic items
1
},
{
// 2- candle, heatsource, fire field, cookfire, stove
1, 1, 1,
1, 2, 1,
1, 1, 1
},
{
// 3 - torch, brazier, campfire, lamppost, candelabra, moongate
0, 1, 1, 1, 0,
1, 2, 2, 2, 1,
1, 2, 3, 2, 1,
1, 2, 2, 2, 1,
0, 1, 1, 1, 0
},
{
// 4 - 20:00, eclipse, dungeon
0, 0, 1, 1, 1, 0, 0,
0, 1, 2, 2, 2, 1, 0,
1, 2, 3, 3, 3, 2, 1,
1, 2, 3, 4, 3, 2, 1,
1, 2, 3, 3, 3, 2, 1,
0, 1, 2, 2, 2, 1, 0,
0, 0, 1, 1, 1, 0, 0
},
{
// 5 - 5:00, 19:50
0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 1, 1, 2, 2, 2, 1, 1, 0,
0, 1, 2, 3, 3, 3, 2, 1, 0,
1, 2, 3, 4, 4, 4, 3, 2, 1,
1, 2, 3, 4, 4, 4, 3, 2, 1,
1, 2, 3, 4, 4, 4, 3, 2, 1,
0, 1, 2, 3, 3, 3, 2, 1, 0,
0, 1, 1, 2, 2, 2, 1, 1, 0,
0, 0, 0, 1, 1, 1, 0, 0, 0,
},
{
// 6 - 5:10, 19:40
0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0,
0, 1, 2, 2, 3, 3, 3, 2, 2, 1, 0,
0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0,
1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1,
1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1,
1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1,
0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0,
0, 1, 2, 2, 3, 3, 3, 2, 2, 1, 0,
0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0
},
{
// 7 - 5:20, 19:30
0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0,
0, 1, 2, 2, 3, 3, 3, 2, 2, 1, 0,
1, 2, 3, 3, 4, 4, 4, 3, 3, 2, 1,
1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1,
2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2,
2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2,
2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2,
1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1,
1, 2, 3, 3, 4, 4, 4, 3, 3, 2, 1,
0, 1, 2, 2, 3, 3, 3, 2, 2, 1, 0,
0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0
},
{
// 8- 5:30, 19:20, torch equipped, light spell
2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2,
2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2,
2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2,
2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2,
2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2,
2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2,
2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2
},
{
// 9 - 5:40, 19:10
3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3,
3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3,
3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3
},
{
// 10 - 5:50 19:00
3, 3, 3, 4, 4, 4, 4, 4, 3, 3, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
3, 3, 3, 4, 4, 4, 4, 4, 3, 3, 3
}
};
void Screen::clearalphamap8(uint16 x, uint16 y, uint16 w, uint16 h, uint8 opacity, bool party_light_source) {
switch (lighting_style) {
default:
case LightingNone:
return;
case LightingSmooth:
shading_ambient = opacity;
break;
case LightingOriginal:
if (opacity < 0xFF)
shading_ambient = 0;
else
shading_ambient = 0xFF;
break;
}
if (shading_data == nullptr) {
shading_rect.left = x;
shading_rect.top = y;
if (lighting_style == LightingOriginal) {
shading_rect.setWidth(w + (SHADING_BORDER * 2));
shading_rect.setHeight(h + (SHADING_BORDER * 2));
} else { // LightingSmooth
shading_rect.setWidth((w + (SHADING_BORDER * 2)) * 16 + 8);
shading_rect.setHeight((h + (SHADING_BORDER * 2)) * 16 + 8);
}
shading_data = (byte *)malloc(sizeof(byte) * shading_rect.width() * shading_rect.height());
if (shading_data == nullptr) {
/* We couldn't allocate memory for the opacity map, so just disable lighting */
shading_ambient = 0xFF;
return;
}
buildalphamap8();
}
if (shading_ambient == 0xFF) {
} else {
memset(shading_data, shading_ambient, sizeof(char)*shading_rect.width() * shading_rect.height());
}
sint16 x_off;
if (Game::get_game()->is_original_plus_full_map())
x_off = - Game::get_game()->get_background()->get_border_width();
else
x_off = 0;
//Light globe around the avatar
if (lighting_style == LightingOriginal)
drawalphamap8globe((shading_rect.width() - 1 + x_off / 16) / 2 - SHADING_BORDER, (shading_rect.height() - 1) / 2 - SHADING_BORDER, opacity / 20 + 4); //range 4 - 10
else if (lighting_style == LightingSmooth)
drawalphamap8globe((((shading_rect.width() - 8 + x_off) / 16) - 1) / 2 - SHADING_BORDER, (((shading_rect.height() - 8) / 16) - 1) / 2 - SHADING_BORDER, party_light_source ? 5 : 4);
}
void Screen::buildalphamap8() {
//Build three globes for 5 intensities
for (int i = 0; i < NUM_GLOBES; i++) {
shading_globe[i] = (uint8 *)malloc(sqr(globeradius[i]));
for (int y = 0; y < globeradius[i]; y++) {
for (int x = 0; x < globeradius[i]; x++) {
float r;
//Distance from center
r = sqrtf(sqr((y - globeradius_2[i])) + sqr((x - globeradius_2[i])));
//Unitize
r /= sqrtf(sqr(globeradius_2[i]) + sqr(globeradius_2[i]));
//Calculate brightness
r = (float)exp(-(10 * r * r));
//Fit into a byte
r *= 255;
//Place it
shading_globe[i][y * globeradius[i] + x] = (uint8)r;
}
}
}
//Get the three shading tiles (for original-style dithered lighting)
Game *game = Game::get_game();
int game_type;
config->value("config/GameType", game_type);
if (game_type == NUVIE_GAME_U6 || game_type == NUVIE_GAME_SE) {
shading_tile[0] = game->get_map_window()->get_tile_manager()->get_tile(444)->data;
shading_tile[1] = game->get_map_window()->get_tile_manager()->get_tile(445)->data;
shading_tile[2] = game->get_map_window()->get_tile_manager()->get_tile(446)->data;
shading_tile[3] = game->get_map_window()->get_tile_manager()->get_tile(447)->data;
} else { //NUVIE_GAME_MD
shading_tile[0] = game->get_map_window()->get_tile_manager()->get_tile(268)->data;
shading_tile[1] = game->get_map_window()->get_tile_manager()->get_tile(269)->data;
shading_tile[2] = game->get_map_window()->get_tile_manager()->get_tile(270)->data;
shading_tile[3] = game->get_map_window()->get_tile_manager()->get_tile(271)->data;
}
}
void Screen::drawalphamap8globe(sint16 x, sint16 y, uint16 r) {
// check shouldn't be needed since items only have 3 intensites
//Clamp lighting globe size to 0-4 (5 levels) // 4 - 10 (7 levels) now in orig_style now like original
// if( r > NUM_GLOBES && lighting_style != LightingOriginal)
// r = NUM_GLOBES;
if (r < 1)
return;
if (shading_ambient == 0xFF)
return;
if (lighting_style == LightingNone)
return;
if (lighting_style == LightingOriginal) {
uint8 rad;
if (r < 6)
rad = r - 1;
else
rad = 5;
x += SHADING_BORDER;
y += SHADING_BORDER;
//Draw using "original" lighting
for (int j = 0; j <= rad * 2; j++)
for (int i = 0; i <= rad * 2; i++) {
if (x + i - rad < 0 || x + i - rad >= shading_rect.width())
continue;
if (y + j - rad < 0 || y + j - rad >= shading_rect.height())
continue;
shading_data[(y + j - rad)*shading_rect.width() + (x + i - rad)] = MIN(shading_data[(y + j - rad) * shading_rect.width() + (x + i - rad)] + TileGlobe[r - 1][j * (rad * 2 + 1) + i], 4);
}
return;
}
x = (x + SHADING_BORDER) * 16 + 8;
y = (y + SHADING_BORDER) * 16 + 8;
//Draw using "smooth" lighting
//The x and y are relative to (0,0) of the mapwindow itself, and are absolute coordinates, so are i and j
r--;
for (int i = -globeradius_2[r]; i < globeradius_2[r]; i++)
for (int j = -globeradius_2[r]; j < globeradius_2[r]; j++) {
if ((y + i) - 1 < 0 ||
(x + j) - 1 < 0 ||
(y + i) + 1 > shading_rect.height() ||
(x + j) + 1 > shading_rect.width())
continue;
shading_data[(y + i)*shading_rect.width() + (x + j)] = MIN(shading_data[(y + i) * shading_rect.width() + (x + j)] + shading_globe[r][(i + globeradius_2[r]) * globeradius[r] + (j + globeradius_2[r])], 255);
}
}
void Screen::blitalphamap8(sint16 x, sint16 y, Common::Rect *clip_rect) {
//pixel = (dst*(1-alpha))+(src*alpha) for an interpolation
//pixel = pixel * alpha for a reduction
//We use a reduction here
if (shading_ambient == 0xFF)
return;
if (lighting_style == LightingNone)
return;
Game *game = Game::get_game();
if (lighting_style == LightingOriginal) {
for (int j = SHADING_BORDER; j < shading_rect.height() - SHADING_BORDER; j++) {
for (int i = SHADING_BORDER; i < shading_rect.width() - SHADING_BORDER; i++) {
if (shading_data[j * shading_rect.width() + i] < 4)
blit(x + (i - SHADING_BORDER) * 16, y + (j - SHADING_BORDER) * 16, shading_tile[shading_data[j * shading_rect.width() + i]], 8, 16, 16, 16, true, game->get_map_window()->get_clip_rect());
}
}
return;
}
uint16 src_w = shading_rect.width() - (SHADING_BORDER * 2 * 16);
uint16 src_h = shading_rect.height() - (SHADING_BORDER * 2 * 16);
uint16 src_x = SHADING_BORDER * 16;
uint16 src_y = SHADING_BORDER * 16;
const uint8 *src_buf = shading_data;
// clip to screen.
//if(x >= width || y >= height)
// return;
if (x < 0) {
//if(x + src_w <= 0)
// return;
//else
src_w += x;
src_buf += -x;
x = 0;
}
if (y < 0) {
//if(y + src_h <= 0)
// return;
//else
src_h += y;
src_buf += shading_rect.width() * -y;
y = 0;
}
if (x + src_w >= width)
src_w = width - x;
if (y + src_h >= height)
src_h = height - y;
//clip to rect if required.
if (clip_rect) {
//if(x + src_w < clip_rect->left || y + src_h < clip_rect->top)
// return;
if (clip_rect->left > x) {
src_x += (clip_rect->left - x);
src_w -= (clip_rect->left - x);
x = clip_rect->left;
}
if (clip_rect->top > y) {
src_y += (clip_rect->top - y);
src_h -= (clip_rect->top - y);
y = clip_rect->top;
}
if (x + src_w > clip_rect->left + clip_rect->width()) {
//if(clip_rect->left + clip_rect->width() - x <= 0)
// return;
src_w = clip_rect->left + clip_rect->width() - x;
}
if (y + src_h > clip_rect->top + clip_rect->height()) {
//if(clip_rect->top + clip_rect->height() - y <= 0)
// return;
src_h = clip_rect->top + clip_rect->height() - y;
}
src_buf += src_y * shading_rect.width() + src_x;
}
switch (_renderSurface->bits_per_pixel) {
case 16: {
uint16 *pixels16 = (uint16 *)_renderSurface->pixels;
pixels16 += y * _renderSurface->w + x;
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels16[j] = (((unsigned char)(((float)((pixels16[j] & _renderSurface->Rmask) >> _renderSurface->Rshift)) * (float)(src_buf[j]) / 255.0f)) << _renderSurface->Rshift) | //R
(((unsigned char)(((float)((pixels16[j] & _renderSurface->Gmask) >> _renderSurface->Gshift)) * (float)(src_buf[j]) / 255.0f)) << _renderSurface->Gshift) | //G
(((unsigned char)(((float)((pixels16[j] & _renderSurface->Bmask) >> _renderSurface->Bshift)) * (float)(src_buf[j]) / 255.0f)) << _renderSurface->Bshift); //B
}
pixels16 += _renderSurface->w;
src_buf += shading_rect.width();
}
break;
}
case 24:
case 32: {
uint32 *pixels = (uint32 *)_renderSurface->pixels;
pixels += y * _renderSurface->w + x;
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels[j] = (((unsigned char)(((float)((pixels[j] & _renderSurface->Rmask) >> _renderSurface->Rshift)) * (float)(src_buf[j]) / 255.0f)) << _renderSurface->Rshift) | //R
(((unsigned char)(((float)((pixels[j] & _renderSurface->Gmask) >> _renderSurface->Gshift)) * (float)(src_buf[j]) / 255.0f)) << _renderSurface->Gshift) | //G
(((unsigned char)(((float)((pixels[j] & _renderSurface->Bmask) >> _renderSurface->Bshift)) * (float)(src_buf[j]) / 255.0f)) << _renderSurface->Bshift); //B
}
pixels += _renderSurface->w;
src_buf += shading_rect.width();
}
break;
}
default:
DEBUG(0, LEVEL_ERROR, "Screen::blitalphamap8() cannot handle your screen _renderSurface depth of %d\n", _renderSurface->bits_per_pixel);
break;
}
}
/* Return an 8bit _renderSurface. Source format is assumed to be identical to screen. */
Graphics::ManagedSurface *Screen::create_sdl_surface_8(const byte *src_buf, uint16 src_w, uint16 src_h) {
Graphics::ManagedSurface *new_surface = new Graphics::ManagedSurface(src_w, src_h,
Graphics::PixelFormat::createFormatCLUT8());
byte *pixels = (byte *)new_surface->getPixels();
if (_renderSurface->bits_per_pixel == 16) {
const uint16 *src = (const uint16 *)src_buf;
for (int p = 0; p < (src_w * src_h); p++)
for (int i = 0; i < 256; i++) // convert to 8bpp
if (src[p] == (uint16)_renderSurface->colour32[i]) {
pixels[p] = i;
break;
}
} else {
const uint32 *src = (const uint32 *)src_buf;
for (int p = 0; p < (src_w * src_h); p++)
for (int i = 0; i < 256; i++)
if (src[p] == _renderSurface->colour32[i]) {
pixels[p] = i;
break;
}
}
return new_surface;
}
Graphics::ManagedSurface *Screen::create_sdl_surface_from(const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch) {
Graphics::ManagedSurface *new_surface = RenderSurface::createSurface(src_w, src_h, _renderSurface->getFormat());
if (_renderSurface->bits_per_pixel == 16) {
uint16 *pixels = (uint16 *)new_surface->getPixels();
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels[j] = (uint16)_renderSurface->colour32[src_buf[j]];
}
src_buf += src_pitch;
pixels += src_pitch; //_renderSurface->pitch;
}
} else {
uint32 *pixels = (uint32 *)new_surface->getPixels();
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++) {
pixels[j] = _renderSurface->colour32[src_buf[j]];
}
src_buf += src_pitch;
pixels += src_w;
}
}
return new_surface;
}
void Screen::update() {
_rawSurface->markAllDirty();
_rawSurface->update();
}
void Screen::update(int x, int y, uint16 w, uint16 h) {
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (x > width)
return;
if (y > height)
return;
if ((x + w) > width)
w = width - x;
if ((y + h) > height)
h = height - y;
// Get the subarea, which internally adds a dirty rect for the given area
_rawSurface->getSubArea(Common::Rect(x, y, x + w, y + h));
}
void Screen::performUpdate() {
_rawSurface->update();
}
void Screen::set_screen_mode() {
const Graphics::PixelFormat SCREEN_FORMAT(2, 5, 6, 5, 0, 11, 5, 0, 0);
initGraphics(width, height, &SCREEN_FORMAT);
_rawSurface = new Graphics::Screen(width, height, SCREEN_FORMAT);
_renderSurface = CreateRenderSurface(_rawSurface);
}
bool Screen::is_fullscreen() const {
return g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
}
bool Screen::toggle_fullscreen() {
set_fullscreen(!is_fullscreen());
return true;
}
bool Screen::set_fullscreen(bool value) {
g_system->beginGFXTransaction();
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, value);
g_system->endGFXTransaction();
return true;
}
//Note! assumes area divides evenly by down_scale factor
byte *Screen::copy_area(const Common::Rect *area, uint16 down_scale) {
if (_renderSurface->bits_per_pixel == 16)
return copy_area16(area, down_scale);
return copy_area32(area, down_scale);
}
byte *Screen::copy_area16(const Common::Rect *area, uint16 down_scale) {
Graphics::ManagedSurface *main_surface = get_sdl_surface();
byte *dst_pixels = new unsigned char[((area->width() / down_scale) * (area->height() / down_scale)) * 3];
byte *ptr = dst_pixels;
const Graphics::PixelFormat *fmt = &main_surface->format;
for (int y = 0; y < area->height(); y += down_scale) {
for (int x = 0; x < area->width(); x += down_scale) {
uint32 r = 0;
uint32 g = 0;
uint32 b = 0;
const uint16 *src_pixels = (const uint16 *)main_surface->getPixels();
src_pixels += ((area->top + y) * _renderSurface->w + (area->left + x));
for (int y1 = 0; y1 < down_scale; y1++) {
for (int x1 = 0; x1 < down_scale; x1++) {
uint32 ra = *src_pixels & fmt->rMax();
ra >>= fmt->rShift;
ra <<= fmt->rLoss;
uint32 ga = *src_pixels & fmt->gMax();
ga >>= fmt->gShift;
ga <<= fmt->gLoss;
uint32 ba = *src_pixels & fmt->bMax();
ba >>= fmt->bShift;
ba <<= fmt->bLoss;
r += ra;
g += ga;
b += ba;
src_pixels++;
}
src_pixels += _renderSurface->w;
}
ptr[0] = (uint8)(r / (down_scale * down_scale));
ptr[1] = (uint8)(g / (down_scale * down_scale));
ptr[2] = (uint8)(b / (down_scale * down_scale));
ptr += 3;
}
}
return dst_pixels;
}
byte *Screen::copy_area32(const Common::Rect *area, uint16 down_scale) {
Graphics::ManagedSurface *main_surface = get_sdl_surface();
byte *dst_pixels = new unsigned char[((area->width() / down_scale) * (area->height() / down_scale)) * 3];
byte *ptr = dst_pixels;
const Graphics::PixelFormat *fmt = &main_surface->format;
for (int y = 0; y < area->height(); y += down_scale) {
for (int x = 0; x < area->width(); x += down_scale) {
uint32 r = 0;
uint32 g = 0;
uint32 b = 0;
const uint32 *src_pixels = (const uint32 *)main_surface->getPixels();
src_pixels += ((area->top + y) * _renderSurface->w + (area->left + x));
for (int y1 = 0; y1 < down_scale; y1++) {
for (int x1 = 0; x1 < down_scale; x1++) {
uint32 ra = *src_pixels & fmt->rMax();
ra >>= fmt->rShift;
ra <<= fmt->rLoss;
uint32 ga = *src_pixels & fmt->gMax();
ga >>= fmt->gShift;
ga <<= fmt->gLoss;
uint32 ba = *src_pixels & fmt->bMax();
ba >>= fmt->bShift;
ba <<= fmt->bLoss;
r += ra;
g += ga;
b += ba;
src_pixels++;
}
src_pixels += _renderSurface->w;
}
ptr[0] = (uint8)(r / (down_scale * down_scale));
ptr[1] = (uint8)(g / (down_scale * down_scale));
ptr[2] = (uint8)(b / (down_scale * down_scale));
ptr += 3;
}
}
return dst_pixels;
}
// _renderSurface -> byte *
// (nullptr area = entire screen)
byte *Screen::copy_area(const Common::Rect *area, byte *buf) {
Common::Rect screen_area(0, 0, _renderSurface->w, _renderSurface->h);
if (!area)
area = &screen_area;
if (_renderSurface->bits_per_pixel == 16)
return copy_area16(area, buf);
return copy_area32(area, buf);
}
// byte * -> _renderSurface
// byte * -> target (src area still means location on screen, not relative to target)
// (nullptr area = entire screen)
void Screen::restore_area(byte *pixels, const Common::Rect *area,
byte *target, const Common::Rect *target_area, bool free_src) {
Common::Rect screen_area(0, 0, _renderSurface->w, _renderSurface->h);
if (!area)
area = &screen_area;
if (_renderSurface->bits_per_pixel == 16)
restore_area16(pixels, area, target, target_area, free_src);
else
restore_area32(pixels, area, target, target_area, free_src);
}
byte *Screen::copy_area32(const Common::Rect *area, byte *buf) {
uint32 *copied = (uint32 *)buf;
if (buf == nullptr) {
copied = (uint32 *)malloc(area->width() * area->height() * 4);
}
uint32 *dest = copied;
const uint32 *src = (const uint32 *)_renderSurface->pixels;
uint16 src_x_off = ABS(area->left);
uint16 src_y_off = ABS(area->top);
uint16 src_w = area->width();
uint16 src_h = area->height();
if (area->left < 0) {
src_x_off = 0;
src_w += area->left;
dest += ABS(area->left);
}
if (area->top < 0) {
src_y_off = 0;
src_h += area->top;
dest += (area->width() * ABS(area->top));
}
if (src_x_off + src_w > (int)_renderSurface->w) {
src_w -= ((src_x_off + src_w) - _renderSurface->w);
}
if (src_y_off + src_h > (int)_renderSurface->h) {
src_h -= ((src_y_off + src_h) - _renderSurface->h);
}
src += src_y_off * _renderSurface->w + src_x_off;
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++)
dest[j] = src[j];
dest += area->width();
src += _renderSurface->w;
}
return (byte *)copied;
}
void Screen::restore_area32(byte *pixels, const Common::Rect *area,
byte *target, const Common::Rect *target_area, bool free_src) {
const uint32 *src = (const uint32 *)pixels;
uint32 *dest = (uint32 *)_renderSurface->pixels;
dest += area->top * _renderSurface->w + area->left;
if (target) { // restore to target instead of screen
dest = (uint32 *)target;
dest += (area->top - target_area->top) * target_area->width() + (area->left - target_area->left);
}
for (int i = 0; i < area->height(); i++) {
for (int j = 0; j < area->width(); j++)
dest[j] = src[j];
src += area->width();
dest += target ? target_area->width() : _renderSurface->w;
}
if (free_src) {
free(pixels);
}
}
byte *Screen::copy_area16(const Common::Rect *area, byte *buf) {
uint16 *copied = (uint16 *)buf;
if (buf == nullptr) {
copied = (uint16 *)malloc(area->width() * area->height() * 2);
}
uint16 *dest = copied;
const uint16 *src = (const uint16 *)_renderSurface->pixels;
uint16 src_x_off = ABS(area->left);
uint16 src_y_off = ABS(area->top);
uint16 src_w = area->width();
uint16 src_h = area->height();
if (area->left < 0) {
src_x_off = 0;
src_w += area->left;
dest += ABS(area->left);
}
if (area->top < 0) {
src_y_off = 0;
src_h += area->top;
dest += (area->width() * ABS(area->top));
}
if (src_x_off + src_w > (int)_renderSurface->w) {
src_w -= ((src_x_off + src_w) - _renderSurface->w);
}
if (src_y_off + src_h > (int)_renderSurface->h) {
src_h -= ((src_y_off + src_h) - _renderSurface->h);
}
src += src_y_off * _renderSurface->w + src_x_off;
for (int i = 0; i < src_h; i++) {
for (int j = 0; j < src_w; j++)
dest[j] = src[j];
dest += area->width();
src += _renderSurface->w;
}
return (byte *)copied;
}
void Screen::restore_area16(byte *pixels, const Common::Rect *area,
byte *target, const Common::Rect *target_area, bool free_src) {
const uint16 *src = (const uint16 *)pixels;
uint16 *dest = (uint16 *)_renderSurface->pixels;
dest += area->top * _renderSurface->w + area->left;
if (target) { // restore to target instead of screen
dest = (uint16 *)target;
dest += (area->top - target_area->top) * target_area->width() + (area->left - target_area->left);
}
for (int i = 0; i < area->height(); i++) {
for (int j = 0; j < area->width(); j++)
dest[j] = src[j];
src += area->width();
dest += target ? target_area->width() : _renderSurface->w;
}
if (free_src) {
free(pixels);
}
}
void Screen::draw_line(int sx, int sy, int ex, int ey, uint8 color) {
if (_renderSurface == nullptr)
return;
_renderSurface->draw_line(sx, sy, ex, ey, color);
return;
}
void Screen::get_mouse_location(int *x, int *y) const {
Common::Point pt = Events::get()->getMousePos();
*x = pt.x;
*y = pt.y;
}
void Screen::set_non_square_pixels(bool value) {
// No implementation
}
} // End of namespace Nuvie
} // End of namespace Ultima