ULTIMA8: Graphics refactor, use more common code

Try to use more of the built-in ScummVM rendering pipeline and remove redundant
types where possible.  Unfortunately this is a bit of a mega-commit because all
the pieces were tied together, but the main changes are:

* Remove the Texture types, as they add little over ManagedSurface
* Remove the ScalerGump as we no longer use it - we should be using the
  built-in ScummVM scalers
* Remove the Scaler types - the only remaining user after removing ScalerGump
  was in hte AVI player.  There we manually add the Crusader style interlaced
  scaling, which was an outstanding TODO anyway.
* Remove now-unused functions from the RenderSurface family
* Remove the "default" mouse cursor as we never use it in ScummVM
* Remove the memset_n header which duplicates Common::Fill functions (fixes
  #11969)
* Remove the fixed-width bitmap fonts which were used for the Pentagram
  console.

I've tested the following things that this had the potential to break:

* U8 game, credits, movies, minimap, and ttf rendering
* Crusader game and movies
* Debug tools (shape viewer, touch-highlight)
This commit is contained in:
Matthew Duggan 2021-01-03 11:03:35 +09:00
parent ec53ee1760
commit 28bb304812
50 changed files with 162 additions and 2256 deletions

View File

@ -1,4 +0,0 @@
[font]
path=@data/fixedfont.tga
height=8
width=8

View File

@ -1,6 +0,0 @@
[font]
path=@data/fixedfont12.tga
height=12
width=11
align_x=16
align_y=16

View File

@ -427,7 +427,6 @@ MODULE_OBJS := \
ultima8/graphics/palette.o \
ultima8/graphics/palette_fader_process.o \
ultima8/graphics/palette_manager.o \
ultima8/graphics/point_scaler.o \
ultima8/graphics/raw_shape_frame.o \
ultima8/graphics/render_surface.o \
ultima8/graphics/shape.o \
@ -436,14 +435,9 @@ MODULE_OBJS := \
ultima8/graphics/shape_info.o \
ultima8/graphics/skf_player.o \
ultima8/graphics/soft_render_surface.o \
ultima8/graphics/texture.o \
ultima8/graphics/texture_bitmap.o \
ultima8/graphics/texture_png.o \
ultima8/graphics/type_flags.o \
ultima8/graphics/wpn_ovlay_dat.o \
ultima8/graphics/xform_blend.o \
ultima8/graphics/texture_targa.o \
ultima8/graphics/fonts/fixed_width_font.o \
ultima8/graphics/fonts/font.o \
ultima8/graphics/fonts/font_manager.o \
ultima8/graphics/fonts/font_shape_archive.o \
@ -490,7 +484,6 @@ MODULE_OBJS := \
ultima8/gumps/readable_gump.o \
ultima8/gumps/remorse_menu_gump.o \
ultima8/gumps/resizable_gump.o \
ultima8/gumps/scaler_gump.o \
ultima8/gumps/scroll_gump.o \
ultima8/gumps/shape_viewer_gump.o \
ultima8/gumps/slider_gump.o \

View File

@ -77,7 +77,7 @@ public:
GumpShapeArchive *getGumps() const {
return _gumps;
}
Shape *getMouse() const {
const Shape *getMouse() const {
return _mouse;
}
MusicFlex *getMusic() const {

View File

@ -48,6 +48,8 @@ AVIPlayer::AVIPlayer(Common::SeekableReadStream *rs, int width, int height, cons
}
_xoff = _width / 2 - (vidWidth / 2);
_yoff = _height / 2 - (vidHeight / 2);
_currentFrame.create(vidWidth, vidHeight, _decoder->getPixelFormat());
_currentFrame.fillRect(Common::Rect(0, 0, vidWidth, vidHeight), 0);
}
AVIPlayer::~AVIPlayer() {
@ -96,24 +98,26 @@ void AVIPlayer::paint(RenderSurface *surf, int /*lerp*/) {
else
pal = _decoder->getPalette();
_currentFrame.loadSurface8Bit(frame, pal);
_currentFrame.setPalette(pal, 0, 256);
}
if (_doubleSize) {
assert(_currentFrame.w == frame->w * 2 && _currentFrame.h == frame->h * 2);
for (int y = 0; y < frame->h; y++) {
const uint8 *srcPixel = static_cast<const uint8 *>(frame->getPixels()) + frame->pitch * y;
uint8 *dstPixels = static_cast<uint8 *>(_currentFrame.getPixels()) + _currentFrame.pitch * y * 2;
for (int x = 0; x < frame->w; x++) {
dstPixels[x * 2] = *srcPixel;
dstPixels[x * 2 + 1] = *srcPixel;
srcPixel++;
}
}
} else {
_currentFrame.loadSurface(frame);
_currentFrame.blitFrom(*frame);
}
}
// TODO: Crusader has a CRT-like scaling which it uses in some
// movies too (eg, T02 for the intro). For now just point-scale.
if (_doubleSize) {
const Scaler *pointScaler = &Ultima8Engine::get_instance()->point_scaler;
bool ok = surf->ScalerBlit(&_currentFrame, 0, 0, _currentFrame.w, _currentFrame.h,
_xoff, _yoff, _currentFrame.w * 2, _currentFrame.h * 2,
pointScaler, false);
assert(ok);
} else {
surf->Blit(&_currentFrame, 0, 0, _currentFrame.w, _currentFrame.h,
_xoff, _yoff);
}
surf->Blit(&_currentFrame, 0, 0, _currentFrame.w, _currentFrame.h,
_xoff, _yoff);
}
void AVIPlayer::run() {

View File

@ -52,7 +52,7 @@ private:
bool _playing;
Video::AVIDecoder *_decoder;
Texture _currentFrame;
Graphics::ManagedSurface _currentFrame;
// Width and height of the area we've been given to play back in
uint32 _width;
uint32 _height;

View File

@ -41,34 +41,36 @@ namespace Ultima8 {
// Desc: Constructor for BaseSoftRenderSurface from a managed surface
//
BaseSoftRenderSurface::BaseSoftRenderSurface(Graphics::ManagedSurface *s) :
_pixels(nullptr), _pixels00(nullptr), _zBuffer(nullptr),
_zBuffer00(nullptr), _bytesPerPixel(0), _bitsPerPixel(0), _formatType(0),
_ox(0), _oy(0), _width(0), _height(0), _pitch(0), _zPitch(0),
_pixels(nullptr), _pixels00(nullptr), _bytesPerPixel(0), _bitsPerPixel(0), _formatType(0),
_ox(0), _oy(0), _width(0), _height(0), _pitch(0),
_flipped(false), _clipWindow(0, 0, 0, 0), _lockCount(0),
_surface(s), _rttTex(nullptr) {
_surface(s) {
_clipWindow.setWidth(_width = _surface->w);
_clipWindow.setHeight(_height = _surface->h);
_pitch = _surface->pitch;
_bitsPerPixel = _surface->format.bpp();
_bytesPerPixel = _surface->format.bytesPerPixel;
RenderSurface::_format.bytesPerPixel = _bytesPerPixel;
RenderSurface::_format.rLoss = _surface->format.rLoss;
RenderSurface::_format.gLoss = _surface->format.gLoss;
RenderSurface::_format.bLoss = _surface->format.bLoss;
RenderSurface::_format.aLoss = _surface->format.aLoss;
RenderSurface::_format.rLoss16 = _format.rLoss + 8;
RenderSurface::_format.gLoss16 = _format.gLoss + 8;
RenderSurface::_format.bLoss16 = _format.bLoss + 8;
RenderSurface::_format.aLoss16 = _format.aLoss + 8;
RenderSurface::_format.rShift = _surface->format.rShift;
RenderSurface::_format.gShift = _surface->format.gShift;
RenderSurface::_format.bShift = _surface->format.bShift;
RenderSurface::_format.aShift = _surface->format.aShift;
RenderSurface::_format.rMask = _surface->format.rMax() << _surface->format.rShift;
RenderSurface::_format.gMask = _surface->format.gMax() << _surface->format.gShift;
RenderSurface::_format.bMask = _surface->format.bMax() << _surface->format.bShift;
RenderSurface::_format.aMask = _surface->format.aMax() << _surface->format.aShift;
// TODO: Slight hack - set the global surface format only once.
if (!RenderSurface::_format.bytesPerPixel) {
RenderSurface::_format.bytesPerPixel = _bytesPerPixel;
RenderSurface::_format.rLoss = _surface->format.rLoss;
RenderSurface::_format.gLoss = _surface->format.gLoss;
RenderSurface::_format.bLoss = _surface->format.bLoss;
RenderSurface::_format.aLoss = _surface->format.aLoss;
RenderSurface::_format.rLoss16 = _format.rLoss + 8;
RenderSurface::_format.gLoss16 = _format.gLoss + 8;
RenderSurface::_format.bLoss16 = _format.bLoss + 8;
RenderSurface::_format.aLoss16 = _format.aLoss + 8;
RenderSurface::_format.rShift = _surface->format.rShift;
RenderSurface::_format.gShift = _surface->format.gShift;
RenderSurface::_format.bShift = _surface->format.bShift;
RenderSurface::_format.aShift = _surface->format.aShift;
RenderSurface::_format.rMask = _surface->format.rMax() << _surface->format.rShift;
RenderSurface::_format.gMask = _surface->format.gMax() << _surface->format.gShift;
RenderSurface::_format.bMask = _surface->format.bMax() << _surface->format.bShift;
RenderSurface::_format.aMask = _surface->format.aMax() << _surface->format.aShift;
}
SetPixelsPointer();
@ -111,127 +113,6 @@ BaseSoftRenderSurface::BaseSoftRenderSurface(Graphics::ManagedSurface *s) :
}
//
// BaseSoftRenderSurface::BaseSoftRenderSurface(int w, int h, int bpp, int rsft, int gsft, int bsft)
//
// Desc: Constructor for Generic BaseSoftRenderSurface
//
BaseSoftRenderSurface::BaseSoftRenderSurface(int w, int h, int bpp,
int rsft, int gsft, int bsft, int asft) :
_pixels(nullptr), _pixels00(nullptr), _zBuffer(nullptr),
_zBuffer00(nullptr), _bytesPerPixel(0), _bitsPerPixel(0), _formatType(0),
_ox(0), _oy(0), _width(0), _height(0), _pitch(0), _zPitch(0),
_flipped(false), _clipWindow(0, 0, 0, 0), _lockCount(0), _surface(nullptr),
_rttTex(nullptr) {
_clipWindow.setWidth(_width = w);
_clipWindow.setHeight(_height = h);
switch (bpp) {
case 15:
_format.rLoss = 3;
_format.gLoss = 3;
_format.bLoss = 3;
_format.aLoss = 7;
bpp = 16;
break;
case 16:
_format.rLoss = 3;
_format.gLoss = 2;
_format.bLoss = 3;
_format.aLoss = 0;
break;
case 32:
_format.rLoss = 0;
_format.gLoss = 0;
_format.bLoss = 0;
_format.aLoss = 0;
break;
default:
break;
}
_pitch = w * bpp / 8;
_bitsPerPixel = bpp;
_bytesPerPixel = bpp / 8;
RenderSurface::_format.bytesPerPixel = _bytesPerPixel;
RenderSurface::_format.rLoss16 = _format.rLoss + 8;
RenderSurface::_format.gLoss16 = _format.gLoss + 8;
RenderSurface::_format.bLoss16 = _format.bLoss + 8;
RenderSurface::_format.aLoss16 = _format.aLoss + 8;
RenderSurface::_format.rShift = rsft;
RenderSurface::_format.gShift = gsft;
RenderSurface::_format.bShift = bsft;
RenderSurface::_format.aShift = asft;
RenderSurface::_format.rMask = (0xFF >> _format.rLoss) << rsft;
RenderSurface::_format.gMask = (0xFF >> _format.gLoss) << gsft;
RenderSurface::_format.bMask = (0xFF >> _format.bLoss) << bsft;
RenderSurface::_format.aMask = (0xFF >> _format.aLoss) << asft;
SetPixelsPointer();
}
//
// BaseSoftRenderSurface::BaseSoftRenderSurface(int w, int h, uint8 *buf)
//
// Desc: Constructor for Generic BaseSoftRenderSurface which matches screen params
//
BaseSoftRenderSurface::BaseSoftRenderSurface(int w, int h, uint8 *buf) :
_pixels(nullptr), _pixels00(nullptr), _zBuffer(nullptr),
_zBuffer00(nullptr), _bytesPerPixel(0), _bitsPerPixel(0), _formatType(0),
_ox(0), _oy(0), _width(0), _height(0), _pitch(0), _zPitch(0),
_flipped(false), _clipWindow(0, 0, 0, 0), _lockCount(0),
_surface(nullptr), _rttTex(nullptr) {
_clipWindow.setWidth(_width = w);
_clipWindow.setHeight(_height = h);
int bpp = RenderSurface::_format.bpp();
_pitch = w * bpp / 8;
_bitsPerPixel = bpp;
_bytesPerPixel = bpp / 8;
_pixels00 = buf;
SetPixelsPointer();
}
//
// BaseSoftRenderSurface::BaseSoftRenderSurface(int w, int h, uint8 *buf)
//
// Desc: Constructor for Generic BaseSoftRenderSurface which matches screen params
//
BaseSoftRenderSurface::BaseSoftRenderSurface(int w, int h) :
_pixels(nullptr), _pixels00(nullptr), _zBuffer(nullptr), _zBuffer00(nullptr),
_bytesPerPixel(0), _bitsPerPixel(0), _formatType(0),
_ox(0), _oy(0), _width(0), _height(0), _pitch(0), _zPitch(0),
_flipped(false), _clipWindow(0, 0, 0, 0), _lockCount(0), _surface(nullptr),
_rttTex(nullptr) {
_clipWindow.setWidth(_width = w);
_clipWindow.setHeight(_height = h);
int bpp = RenderSurface::_format.bpp();
_pitch = w * bpp / 8;
_bitsPerPixel = bpp;
_bytesPerPixel = bpp / 8;
_pixels00 = new uint8[_pitch * _height];
_rttTex = new Texture;
_rttTex->setPixels(_pixels00);
_rttTex->w = _width;
_rttTex->h = _height;
_rttTex->_format = TEX_FMT_NATIVE;
_rttTex->format = RenderSurface::getPixelFormat();
_rttTex->pitch = _pitch;
_rttTex->CalcLOG2s();
SetPixelsPointer();
}
//
// BaseSoftRenderSurface::~BaseSoftRenderSurface()
@ -239,11 +120,6 @@ BaseSoftRenderSurface::BaseSoftRenderSurface(int w, int h) :
// Desc: Destructor
//
BaseSoftRenderSurface::~BaseSoftRenderSurface() {
if (_rttTex) {
delete _rttTex;
delete [] _pixels00;
delete [] _zBuffer00;
}
}
@ -263,10 +139,8 @@ bool BaseSoftRenderSurface::BeginPainting() {
_pitch = _surface->pitch;
if (_flipped) _pitch = -_pitch;
} else {
if (!GenericLock())
return false;
}
// else, nothing to lock.
}
_lockCount++;
@ -305,34 +179,19 @@ bool BaseSoftRenderSurface::EndPainting() {
// Clear pointers
_pixels = _pixels00 = 0;
// Render the screen
// Render the screen if this is it (slight hack..)
Graphics::Screen *screen = dynamic_cast<Graphics::Screen *>(_surface);
assert(screen);
screen->update();
if (screen)
screen->update();
} else {
if (!GenericUnlock())
return false;
}
// else, nothing to unlock.
}
// No error
return true;
}
//
// Texture *BaseSoftRenderSurface::GetSurfaceAsTexture()
//
// Desc: Get the surface as a Texture. Only valid for SecondaryRenderSurfaces
//
Texture *BaseSoftRenderSurface::GetSurfaceAsTexture() {
if (!_rttTex) {
perr << "Error: GetSurfaceAsTexture(): Surface doesn't render-to-texture" << Std::endl;
}
return _rttTex;
}
//
// void BaseSoftRenderSurface::CreateNativePalette(Palette* palette)
//
@ -511,7 +370,6 @@ void BaseSoftRenderSurface::SetFlipped(bool wantFlipped) {
_oy += _clipWindow.top;
_pitch = -_pitch;
_zPitch = -_zPitch;
SetPixelsPointer();

View File

@ -41,10 +41,6 @@ protected:
uint8 *_pixels; // Pointer to logical pixel 0,0
uint8 *_pixels00; // Pointer to physical pixel 0,0
// Depth Buffer
uint16 *_zBuffer; // Pointer to logical pixel 0,0
uint8 *_zBuffer00; // Pointer to physical pixel 0,0
// Pixel Format (also see 'Colour shifting values' later)
int _bytesPerPixel; // 2 or 4
int _bitsPerPixel; // 16 or 32
@ -54,7 +50,6 @@ protected:
int32 _ox, _oy; // Physical Pixel for Logical Origin
int32 _width, _height; // Width and height
int32 _pitch; // Frame buffer pitch (bytes) (could be negated)
int32 _zPitch; // Z Buffer pitch (bytes) (could be negated)
bool _flipped;
// Clipping Rectangle
@ -65,37 +60,18 @@ protected:
Graphics::ManagedSurface *_surface;
// Renderint to a texture
Texture *_rttTex;
// Create from a managed surface
BaseSoftRenderSurface(Graphics::ManagedSurface *);
// Create with Texture
BaseSoftRenderSurface(int w, int h);
// Create Generic
BaseSoftRenderSurface(int w, int h, int bpp, int rsft, int gsft, int bsft, int asft);
BaseSoftRenderSurface(int w, int h, uint8 *buf);
virtual bool GenericLock() {
return true;
}
virtual bool GenericUnlock() {
return true;
}
// Update the Pixels Pointer
void SetPixelsPointer() {
uint8 *pix00 = _pixels00;
uint8 *zbuf00 = _zBuffer00;
if (_flipped) {
pix00 += -_pitch * (_height - 1);
zbuf00 += -_zPitch * (_height - 1);
}
_pixels = pix00 + _ox * _bytesPerPixel + _oy * _pitch;
_zBuffer = reinterpret_cast<uint16 *>(zbuf00 + _ox + _oy * _zPitch);
}
public:
@ -116,10 +92,6 @@ public:
// Returns Error Code on error. Check return code.....
bool EndPainting() override;
// Get the surface as a Texture. Only valid for SecondaryRenderSurfaces
Texture *GetSurfaceAsTexture() override;
//
// Surface Properties
//

View File

@ -1,94 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/graphics/fonts/fixed_width_font.h"
#include "ultima/ultima8/graphics/texture.h"
#include "ultima/ultima8/filesys/idata_source.h"
#include "ultima/ultima8/conf/config_file_manager.h"
#include "ultima/ultima8/filesys/file_system.h"
namespace Ultima {
namespace Ultima8 {
FixedWidthFont *FixedWidthFont::Create(const Std::string &iniroot) {
ConfigFileManager *config = ConfigFileManager::get_instance();
FileSystem *filesys = FileSystem::get_instance();
Std::string filename;
if (!config->get(iniroot + "/font/path", filename)) {
perr << "Error: 'path' key not found in font ini" << Std::endl;
return nullptr;
}
Common::SeekableReadStream *rs = filesys->ReadFile(filename);
if (!rs) {
perr << "Error: Unable to open file " << filename << Std::endl;
return nullptr;
}
Texture *fonttex = Texture::Create(rs, filename.c_str());
if (!fonttex) {
perr << "Error: Unable to read texture " << filename << Std::endl;
// FIXME: This leaks rs
return nullptr;
}
delete rs;
FixedWidthFont *fwf = new FixedWidthFont;
fwf->_tex = fonttex;
if (!config->get(iniroot + "/font/width", fwf->_width)) {
fwf->_width = fwf->_tex->w / 16;
}
if (!config->get(iniroot + "/font/height", fwf->_height)) {
fwf->_height = fwf->_tex->h / 16;
}
if (!config->get(iniroot + "/font/align_x", fwf->_alignX)) {
for (int i = 0; i < 32; i++) {
if (fwf->_width <= (1 << i)) {
fwf->_alignX = 1 << i;
break;
}
}
}
if (!config->get(iniroot + "/font/align_y", fwf->_alignY)) {
for (int i = 0; i < 32; i++) {
if (fwf->_height <= (1 << i)) {
fwf->_alignY = 1 << i;
break;
}
}
}
return fwf;
}
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -1,49 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA8_GRAPHICS_FONTS_FIXEDWIDTHFONT_H
#define ULTIMA8_GRAPHICS_FONTS_FIXEDWIDTHFONT_H
#include "ultima/shared/std/string.h"
namespace Ultima {
namespace Ultima8 {
class Texture;
struct FixedWidthFont {
int _width;
int _height;
int _alignX;
int _alignY;
Texture *_tex;
~FixedWidthFont();
static FixedWidthFont *Create(const Std::string &iniroot);
};
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -46,6 +46,8 @@ void ShapeRenderedText::draw(RenderSurface *surface, int x, int y, bool /*destma
Std::list<PositionedText>::const_iterator iter;
surface->BeginPainting();
for (iter = _lines.begin(); iter != _lines.end(); ++iter) {
int line_x = x + iter->_dims.left;
int line_y = y + iter->_dims.top;
@ -69,6 +71,8 @@ void ShapeRenderedText::draw(RenderSurface *surface, int x, int y, bool /*destma
1, iter->_dims.height());
}
}
surface->EndPainting();
}
void ShapeRenderedText::drawBlended(RenderSurface *surface, int x, int y,

View File

@ -40,12 +40,12 @@ namespace Ultima8 {
// various unicode characters which look like small black circles
static const uint16 BULLETS[] = { 0x2022, 0x30FB, 0x25CF, 0 };
static const Graphics::PixelFormat PF_RGBA(4, 8, 8, 8, 8, 24, 16, 8, 0);
TTFont::TTFont(Graphics::Font *font, uint32 rgb, int borderSize,
bool antiAliased, bool SJIS) :
_borderSize(borderSize), _ttfFont(font), _antiAliased(antiAliased), _SJIS(SJIS),
_pixelFormat(Texture::getPixelFormat()) {
_color = _pixelFormat.RGBToColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xff, rgb & 0xff);
_borderSize(borderSize), _ttfFont(font), _antiAliased(antiAliased), _SJIS(SJIS) {
_color = PF_RGBA.RGBToColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xff, rgb & 0xff);
_bullet = 0;
// scan for a character to use as a conversation option _bullet
@ -139,8 +139,7 @@ RenderedText *TTFont::renderText(const Std::string &text, unsigned int &remainin
resultWidth, resultHeight, cursor);
lineHeight = _ttfFont->getFontHeight();
Texture *texture = new Texture();
texture->create(resultWidth, resultHeight, TEX_FMT_STANDARD);
Graphics::ManagedSurface *texture = new Graphics::ManagedSurface(resultWidth, resultHeight, PF_RGBA);
uint32 *texBuf = (uint32 *)texture->getPixels();
Std::list<PositionedText>::const_iterator iter;
@ -162,13 +161,13 @@ RenderedText *TTFont::renderText(const Std::string &text, unsigned int &remainin
_ttfFont->drawString(&textSurf, unicodeText, 0, 0, resultWidth, 1);
} else {
// Use a high color surface with the specified _color color for text
textSurf.create(resultWidth, lineHeight, _pixelFormat);
textSurf.create(resultWidth, lineHeight, PF_RGBA);
_ttfFont->drawString(&textSurf, unicodeText, 0, 0, resultWidth, _color);
};
// render the text surface into our texture buffer
for (int y = 0; y < textSurf.h; y++) {
byte *surfrow = (byte *)textSurf.getBasePtr(0, y);
const byte *surfrow = (const byte *)textSurf.getBasePtr(0, y);
// CHECKME: _borderSize!
uint32 *bufrow = texBuf + (iter->_dims.top + y + _borderSize) * resultWidth;

View File

@ -32,8 +32,6 @@ namespace Ultima {
namespace Ultima8 {
class TTFont : public Font {
private:
Graphics::PixelFormat _pixelFormat;
public:
TTFont(Graphics::Font *font, uint32 rgb, int bordersize,
bool antiAliased, bool SJIS);

View File

@ -29,7 +29,7 @@
namespace Ultima {
namespace Ultima8 {
TTFRenderedText::TTFRenderedText(Texture *texture, int width, int height,
TTFRenderedText::TTFRenderedText(Graphics::ManagedSurface *texture, int width, int height,
int vLead, TTFont *font) : _texture(texture), _font(font) {
_width = width;
_height = height;

View File

@ -26,6 +26,7 @@
#include "ultima/ultima8/graphics/fonts/rendered_text.h"
#include "ultima/ultima8/graphics/fonts/font.h"
#include "ultima/ultima8/misc/p_dynamic_cast.h"
#include "graphics/managed_surface.h"
namespace Ultima {
namespace Ultima8 {
@ -35,7 +36,7 @@ class Texture;
class TTFRenderedText : public RenderedText {
public:
TTFRenderedText(Texture *texture, int width, int height, int vlead,
TTFRenderedText(Graphics::ManagedSurface *texture, int width, int height, int vlead,
TTFont *font);
~TTFRenderedText() override;
@ -45,7 +46,7 @@ public:
bool destmasked = false) override;
protected:
Texture *_texture;
Graphics::ManagedSurface *_texture;
TTFont *_font;
};

View File

@ -1,305 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/graphics/point_scaler.h"
#include "ultima/ultima8/graphics/manips.h"
namespace Ultima {
namespace Ultima8 {
// Very very simple point scaler
template<class uintX, class Manip, class uintS = uintX> class PointScalerInternal {
public:
static bool Scale(const Texture *tex , int32 sx, int32 sy, int32 sw, int32 sh,
uint8 *pixel, int32 dw, int32 dh, int32 pitch, bool clamp_src) {
// Source buffer pointers
const uintS *texel = reinterpret_cast<const uintS *>(tex->getPixels()) + (sy * tex->w + sx);
int tpitch = tex->w;
const uintS *tline_end = texel + sw;
const uintS *tex_end = texel + sh * tex->w;
int tex_diff = tex->w - sw;
// First detect integer up scalings, since they are 'easy'
bool x_intscale = ((dw / sw) * sw) == dw;
bool y_intscale = ((dh / sh) * sh) == dh;
//
// 2x
//
if ((sw * 2 == dw) && (sh * 2 == dh)) {
uint8 *pixel2 = pixel + pitch;
int p_diff = (pitch * 2) - (dw * sizeof(uintX));
// Src Loop Y
do {
// Src Loop X
do {
uintX p = Manip::copy(*texel);
*(reinterpret_cast<uintX *>(pixel + 0)) = p;
*(reinterpret_cast<uintX *>(pixel + sizeof(uintX))) = p;
*(reinterpret_cast<uintX *>(pixel2 + 0)) = p;
*(reinterpret_cast<uintX *>(pixel2 + sizeof(uintX))) = p;
pixel += sizeof(uintX) * 2;
pixel2 += sizeof(uintX) * 2;
texel++;
} while (texel != tline_end);
pixel += p_diff;
pixel2 += p_diff;
texel += tex_diff;
tline_end += tpitch;
} while (texel != tex_end);
}
//
// Integer scaling, x and y
//
else if (x_intscale && y_intscale) {
int xf = dw / sw;
int yf = dh / sh;
uint8 *px_end = pixel + xf * sizeof(uintX);
uint8 *py_end = pixel + yf * pitch;
int block_w = xf * sizeof(uintX);
int block_h = pitch * yf;
int block_xdiff = pitch - block_w;
int p_diff = block_h - dw * sizeof(uintX);
// Src Loop Y
do {
// Src Loop X
do {
uintX p = Manip::copy(*texel);
//
// Inner loops
//
// Dest Loop Y
do {
// Dest Loop X
do {
*(reinterpret_cast<uintX *>(pixel)) = p;
pixel += sizeof(uintX);
} while (pixel != px_end);
pixel += block_xdiff;
px_end += pitch;
} while (pixel != py_end);
pixel += block_w - block_h;
px_end += block_w - block_h;
py_end += block_w;
texel++;
} while (texel != tline_end);
pixel += p_diff;
py_end += p_diff;
px_end += p_diff;
texel += tex_diff;
tline_end += tpitch;
} while (texel != tex_end);
}
//
// 2x X and Arbitrary Upscaled Y
// Specifically to handle 320x200 -> 640x480
//
else if ((sw * 2 == dw) && (dh >= sh)) {
uint32 pos_y;
uint32 end_y = dh;
uint32 dst_y = 0;
uint8 *next_block = nullptr;
// Src Loop Y
do {
next_block = pixel;
// Src Loop X
do {
pos_y = dst_y;
uintX p = Manip::copy(*texel);
//
// Inner loops
//
pixel = next_block;
next_block = next_block + sizeof(uintX) * 2;
// Dest Loop Y
do {
*(reinterpret_cast<uintX *>(pixel + 0)) = p;
*(reinterpret_cast<uintX *>(pixel + sizeof(uintX))) = p;
pixel += pitch;
pos_y += sh;
} while (pos_y < end_y);
texel++;
} while (texel != tline_end);
pixel -= sizeof(uintX) * (dw - 2);
dst_y = pos_y;
end_y += dh;
texel += tex_diff;
tline_end += tpitch;
} while (texel != tex_end);
}
//
// 1x X and Arbitrary Upscaled Y
// Specifically to handle 640x400 -> 640x480
//
else if ((sw == dw) && (dh >= sh)) {
uint32 pos_y;
uint32 end_y = dh;
uint32 dst_y = 0;
uint8 *next_block = nullptr;
// Src Loop Y
do {
next_block = pixel;
// Src Loop X
do {
pos_y = dst_y;
uintX p = Manip::copy(*texel);
//
// Inner loops
//
pixel = next_block;
next_block = next_block + sizeof(uintX);
// Dest Loop Y
do {
*(reinterpret_cast<uintX *>(pixel)) = p;
pixel += pitch;
pos_y += sh;
} while (pos_y < end_y);
texel++;
} while (texel != tline_end);
pixel -= sizeof(uintX) * (dw - 1);
dst_y = pos_y;
end_y += dh;
texel += tex_diff;
tline_end += tpitch;
} while (texel != tex_end);
}
//
// Arbitrary scaling X and Y (optimized for upscaling)
//
else {
uint32 pos_y = 0, pos_x = 0;
uint32 end_y = dh;
uint32 dst_y = 0;
uint8 *blockline_start = nullptr;
uint8 *next_block = nullptr;
// Src Loop Y
do {
uint32 end_x = dw;
uint32 dst_x = 0;
next_block = pixel;
// Src Loop X
do {
pos_y = dst_y;
const uintX p = Manip::copy(*texel);
//
// Inner loops
//
blockline_start = next_block;
next_block = nullptr;
// Dest Loop Y
while (pos_y < end_y) {
pos_x = dst_x;
pixel = blockline_start;
// Dest Loop X
while (pos_x < end_x) {
*(reinterpret_cast<uintX *>(pixel)) = p;
pixel += sizeof(uintX);
pos_x += sw;
}
if (!next_block) next_block = pixel;
blockline_start += pitch;
pos_y += sh;
}
dst_x = pos_x;
end_x += dw;
texel++;
} while (texel != tline_end);
pixel += pitch - sizeof(uintX) * (dw);
dst_y = pos_y;
end_y += dh;
texel += tex_diff;
tline_end += tpitch;
} while (texel != tex_end);
}
return true;
}
};
PointScaler::PointScaler() : Scaler() {
Scale16Nat = PointScalerInternal<uint16, Manip_Nat2Nat_16, uint16>::Scale;
Scale16Sta = PointScalerInternal<uint16, Manip_Sta2Nat_16, uint32>::Scale;
Scale32Nat = PointScalerInternal<uint32, Manip_Nat2Nat_32, uint32>::Scale;
Scale32Sta = PointScalerInternal<uint32, Manip_Sta2Nat_32, uint32>::Scale;
Scale32_A888 = PointScalerInternal<uint32, Manip_32_A888, uint32>::Scale;
Scale32_888A = PointScalerInternal<uint32, Manip_32_888A, uint32>::Scale;
}
uint32 PointScaler::ScaleBits() const {
return 0xFFFFFFFF;
}
bool PointScaler::ScaleArbitrary() const {
return true;
}
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -1,42 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA8_GRAPHICS_SCALERS_POINTSCALER_H
#define ULTIMA8_GRAPHICS_SCALERS_POINTSCALER_H
#include "ultima/ultima8/graphics/scaler.h"
namespace Ultima {
namespace Ultima8 {
class PointScaler : public Scaler {
public:
PointScaler();
uint32 ScaleBits() const override; //< bits for supported integer scaling
bool ScaleArbitrary() const override; //< supports arbitrary scaling of any degree
};
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -81,8 +81,9 @@ RenderSurface *RenderSurface::CreateSecondaryRenderSurface(uint32 width, uint32
RenderSurface *surf;
// TODO: Change this
if (_format.bytesPerPixel == 4) surf = new SoftRenderSurface<uint32>(width, height);
else surf = new SoftRenderSurface<uint16>(width, height);
Graphics::ManagedSurface *managedSurface = new Graphics::ManagedSurface(width, height, _format);
if (_format.bytesPerPixel == 4) surf = new SoftRenderSurface<uint32>(managedSurface);
else surf = new SoftRenderSurface<uint16>(managedSurface);
return surf;
}

View File

@ -95,12 +95,6 @@ public:
// \return true on success, false on failure
virtual bool EndPainting() = 0;
//! Get the surface as a Texture. Only valid for SecondaryRenderSurfaces
// \note Do not delete the texture.
// \note Do not assume anything about the contents of the Texture object.
// \note It should only be used with Painting and Blitting methods.
virtual Texture *GetSurfaceAsTexture() = 0;
//
// Surface Properties
//
@ -209,19 +203,13 @@ public:
//
//! Blit a region from a Texture (Alpha == 0 -> skipped)
virtual void Blit(const Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend = false) = 0;
virtual void Blit(const Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend = false) = 0;
//! Blit a region from a Texture with a Colour blend (AlphaTex == 0 -> skipped. AlphaCol32 -> Blend Factors)
virtual void FadedBlit(const Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) = 0;
virtual void FadedBlit(const Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) = 0;
//! Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
virtual void MaskedBlit(const Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) = 0;
//! Blit a stretched region from a Texture (Alpha == 0 -> skipped???)
virtual void StretchBlit(const Texture *, int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh, bool clampedges = false) = 0;
//! Blit a region from a Texture using a scaler
virtual bool ScalerBlit(const Texture *, int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh, const Scaler *, bool clampedges = false) = 0;
virtual void MaskedBlit(const Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) = 0;
};

View File

@ -1,122 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA8_GRAPHICS_SCALER_H
#define ULTIMA8_GRAPHICS_SCALER_H
#include "ultima/ultima8/graphics/texture.h"
#include "ultima/ultima8/graphics/render_surface.h"
namespace Ultima {
namespace Ultima8 {
/// Base Scaler class
class Scaler {
friend class hqScaler;
protected:
// Basic scaler function template
typedef bool (*ScalerFunc)(const Texture *tex, int32 sx, int32 sy, int32 sw, int32 sh,
uint8 *pixel, int32 dw, int32 dh, int32 pitch, bool clamp_src);
//
// Basic scaler functions (filled in by the scalers constructor)
//
ScalerFunc Scale16Nat;
ScalerFunc Scale16Sta;
ScalerFunc Scale32Nat;
ScalerFunc Scale32Sta;
ScalerFunc Scale32_A888;
ScalerFunc Scale32_888A;
Scaler() : Scale16Nat(0), Scale16Sta(0), Scale32Nat(0), Scale32Sta(0),
Scale32_A888(0), Scale32_888A(0) {}
public:
//
// Scaler Capabilites
//
virtual uint32 ScaleBits() const = 0; //< bits for supported integer scaling
virtual bool ScaleArbitrary() const = 0; //< supports arbitrary scaling of any degree
//
// Maybe one day... for now we just grab everything from RenderSurface
// virtual bool SetDisplayFormat(const RenderSurface::Format &format);
// Call this to scale a section of the screen
inline bool Scale(const Texture *texture, int32 sx, int32 sy, int32 sw, int32 sh,
uint8 *pixel, int32 dw, int32 dh, int32 pitch, bool clamp_src) const {
// Check to see if we are doing valid integer scalings
if (!ScaleArbitrary()) {
uint32 scale_bits = ScaleBits();
int x_factor = dw / sw;
int y_factor = dh / sh;
// Not integer
if ((x_factor * sw) != dw || (y_factor * sh) != dh) return false;
// Don't support this
if (!(scale_bits & (1 << x_factor))) return false;
// Don't support this
if (!(scale_bits & (1 << y_factor))) return false;
}
if (RenderSurface::_format.bytesPerPixel == 4) {
if (texture->_format == TEX_FMT_NATIVE || (texture->_format == TEX_FMT_STANDARD &&
RenderSurface::_format.aMask == TEX32_A_MASK && RenderSurface::_format.rMask == TEX32_R_MASK &&
RenderSurface::_format.gMask == TEX32_G_MASK && RenderSurface::_format.bMask == TEX32_B_MASK)) {
if (RenderSurface::_format.aMask == 0xFF000000) {
if (!Scale32_A888) return false;
return Scale32_A888(texture, sx, sy, sw, sh, pixel, dw, dh, pitch, clamp_src);
} else if (RenderSurface::_format.aMask == 0x000000FF) {
if (!Scale32_888A) return false;
return Scale32_888A(texture, sx, sy, sw, sh, pixel, dw, dh, pitch, clamp_src);
} else {
if (!Scale32Nat) return false;
return Scale32Nat(texture, sx, sy, sw, sh, pixel, dw, dh, pitch, clamp_src);
}
} else if (texture->_format == TEX_FMT_STANDARD) {
if (!Scale32Sta) return false;
return Scale32Sta(texture, sx, sy, sw, sh, pixel, dw, dh, pitch, clamp_src);
}
}
if (RenderSurface::_format.bytesPerPixel == 2) {
if (texture->_format == TEX_FMT_NATIVE) {
if (!Scale16Nat) return false;
return Scale16Nat(texture, sx, sy, sw, sh, pixel, dw, dh, pitch, clamp_src);
} else if (texture->_format == TEX_FMT_STANDARD) {
if (!Scale16Sta) return false;
return Scale16Sta(texture, sx, sy, sw, sh, pixel, dw, dh, pitch, clamp_src);
}
}
return false;
}
virtual ~Scaler() { }
};
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -80,7 +80,11 @@ SKFPlayer::SKFPlayer(Common::SeekableReadStream *rs, int width, int height, bool
parseEventList(eventlist);
delete eventlist;
_buffer = RenderSurface::CreateSecondaryRenderSurface(_width, _height);
// TODO: Slight hack.. clean me up.
if (RenderSurface::getPixelFormat().bpp() == 16)
_buffer = new SoftRenderSurface<uint16>(new Graphics::ManagedSurface(_width, _height, RenderSurface::getPixelFormat()));
else
_buffer = new SoftRenderSurface<uint32>(new Graphics::ManagedSurface(_width, _height, RenderSurface::getPixelFormat()));
}
SKFPlayer::~SKFPlayer() {
@ -106,9 +110,7 @@ void SKFPlayer::parseEventList(Common::ReadStream *eventlist) {
}
void SKFPlayer::start() {
_buffer->BeginPainting();
_buffer->Fill32(0, 0, 0, _width, _height);
_buffer->EndPainting();
MusicProcess *musicproc = MusicProcess::get_instance();
if (musicproc) musicproc->playMusic(0);
_playing = true;
@ -124,16 +126,14 @@ void SKFPlayer::stop() {
void SKFPlayer::paint(RenderSurface *surf, int /*lerp*/) {
if (!_buffer) return;
Texture *tex = _buffer->GetSurfaceAsTexture();
if (!_fadeLevel) {
surf->Blit(tex, 0, 0, _width, _height, 0, 0);
surf->Blit(_buffer->getRawSurface(), 0, 0, _width, _height, 0, 0);
if (_subs)
_subs->draw(surf, 60, _subtitleY);
} else {
uint32 fade = TEX32_PACK_RGBA(_fadeColour, _fadeColour, _fadeColour,
(_fadeLevel * 255) / FADESTEPS);
surf->FadedBlit(tex, 0, 0, _width, _height, 0, 0, fade);
surf->FadedBlit(_buffer->getRawSurface(), 0, 0, _width, _height, 0, 0, fade);
if (_subs)
_subs->drawBlended(surf, 60, _subtitleY, fade);
}

View File

@ -25,13 +25,13 @@
#include "ultima/shared/std/containers.h"
#include "ultima/ultima8/graphics/movie_player.h"
#include "ultima/ultima8/graphics/base_soft_render_surface.h"
namespace Ultima {
namespace Ultima8 {
struct SKFEvent;
class RawArchive;
class RenderSurface;
class RenderedText;
struct Palette;
@ -64,7 +64,7 @@ private:
unsigned int _timer;
unsigned int _frameRate;
uint8 _fadeColour, _fadeLevel;
RenderSurface *_buffer;
BaseSoftRenderSurface *_buffer;
RenderedText *_subs;
int _subtitleY;
bool _introMusicHack;

View File

@ -26,10 +26,7 @@
#include "ultima/ultima8/graphics/shape.h"
#include "ultima/ultima8/graphics/shape_frame.h"
#include "ultima/ultima8/graphics/palette.h"
#include "ultima/ultima8/graphics/fonts/fixed_width_font.h"
#include "ultima/ultima8/misc/memset_n.h"
#include "ultima/ultima8/graphics/xform_blend.h"
#include "ultima/ultima8/graphics/point_scaler.h"
#include "ultima/ultima8/ultima8.h"
namespace Ultima {
@ -52,36 +49,6 @@ template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(Graphics::Mana
}
//
// SoftRenderSurface::SoftRenderSurface(int w, int h, int bpp, int rsft, int gsft, int bsft)
//
// Desc: Create a Generic SoftRenderSurface
//
template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(int w, int h, int bpp, int rsft, int gsft, int bsft, int asft)
: BaseSoftRenderSurface(w, h, bpp, rsft, gsft, bsft, asft) {
}
//
// SoftRenderSurface::SoftRenderSurface(int w, int h)
//
// Desc: Create a Generic surface that matches current screen parameters
//
template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(int w, int h, uint8 *buf)
: BaseSoftRenderSurface(w, h, buf) {
}
//
// SoftRenderSurface::SoftRenderSurface(int w, int h)
//
// Desc: Create a Render to texture surface
//
template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(int w, int h)
: BaseSoftRenderSurface(w, h) {
}
//
// SoftRenderSurface::Fill32(uint32 rgb, int32 sx, int32 sy, int32 w, int32 h)
//
@ -265,106 +232,30 @@ template<class uintX> void SoftRenderSurface<uintX>::DrawLine32(uint32 rgb, int3
//
// SoftRenderSurface::Blit(Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend)
// SoftRenderSurface::Blit(Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend)
//
// Desc: Blit a region from a Texture (Alpha == 0 -> skipped)
//
template<class uintX> void SoftRenderSurface<uintX>::Blit(const Texture *_tex, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend) {
// Clamp or wrap or return?
if (sx + w > static_cast<int32>(_tex->w))
return;
// Clamp or wrap or return?
if (sy + h > static_cast<int32>(_tex->h))
return;
if (sx < 0 || sy < 0)
return;
// Clip to window
int px = dx, py = dy;
Rect rect(dx, dy, dx + w, dy + h);
rect.clip(_clipWindow);
dx = rect.left;
dy = rect.top;
w = rect.width();
h = rect.height();
if (!w || !h) return;
// Adjust source x and y
if (px != dx) sx += dx - px;
if (py != dy) sy += dy - py;
uint8 *pixel = _pixels + dy * _pitch + dx * sizeof(uintX);
uint8 *line_end = pixel + w * sizeof(uintX);
uint8 *end = pixel + h * _pitch;
int diff = _pitch - w * sizeof(uintX);
if (_tex->_format == TEX_FMT_STANDARD) {
uint32 *texel = (uint32 *)_tex->getBasePtr(sx, sy);
int tex_diff = _tex->w - w;
while (pixel != end) {
if (!alpha_blend) while (pixel != line_end) {
if (*texel & TEX32_A_MASK) {
*(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(PACK_RGB8(TEX32_R(*texel), TEX32_G(*texel), TEX32_B(*texel)));
}
pixel += sizeof(uintX);
texel++;
}
else while (pixel != line_end) {
uint32 alpha = *texel & TEX32_A_MASK;
if (alpha == 0xFF) {
*(reinterpret_cast<uintX *>(pixel)) = static_cast<uintX>(PACK_RGB8(TEX32_R(*texel), TEX32_G(*texel), TEX32_B(*texel)));
} else if (alpha) {
uintX *dest = reinterpret_cast<uintX *>(pixel);
*dest = static_cast<uintX>(BlendPreModFast(*texel, *dest));
}
pixel += sizeof(uintX);
texel++;
}
line_end += _pitch;
pixel += diff;
texel += tex_diff;
}
} else if (_tex->_format == TEX_FMT_NATIVE) {
const uintX *texel = reinterpret_cast<const uintX *>(_tex->getBasePtr(sx, sy));
int tex_diff = _tex->w - w;
while (pixel != end) {
while (pixel != line_end) {
// Uh, not supported right now
//if (*texel & RenderSurface::a_mask)
{
*(reinterpret_cast<uintX *>(pixel)) = *texel;
}
pixel += sizeof(uintX);
texel++;
}
line_end += _pitch;
pixel += diff;
texel += tex_diff;
}
}
template<class uintX> void SoftRenderSurface<uintX>::Blit(const Graphics::ManagedSurface *tex, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend) {
Common::Rect srect = Common::Rect(sx, sy, sx + w, sy + h);
Common::Point dpoint = Common::Point(_ox + dx, _oy + dy);
_surface->blitFrom(*tex, srect, dpoint);
}
//
// void SoftRenderSurface::FadedBlit(Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32)
// void SoftRenderSurface::FadedBlit(Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32)
//
// Desc: Blit a region from a Texture (Alpha == 0 -> skipped)
//
template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(const Texture *_tex, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(const Graphics::ManagedSurface *tex, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
// Clamp or wrap or return?
if (w > static_cast<int32>(_tex->w))
if (w > static_cast<int32>(tex->w))
return;
// Clamp or wrap or return?
if (h > static_cast<int32>(_tex->h))
if (h > static_cast<int32>(tex->h))
return;
// Clip to window
@ -394,9 +285,11 @@ template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(const Texture *_t
uint32 g = (TEX32_G(col32) * a);
uint32 b = (TEX32_B(col32) * a);
if (_tex->_format == TEX_FMT_STANDARD) {
uint32 *texel = (uint32 *)_tex->getBasePtr(sx, sy);
int tex_diff = _tex->w - w;
const Graphics::PixelFormat &texformat = tex->rawSurface().format;
if (texformat.bpp() == 32) {
const uint32 *texel = static_cast<const uint32 *>(tex->getBasePtr(sx, sy));
int tex_diff = tex->w - w;
while (pixel != end) {
if (!alpha_blend) while (pixel != line_end) {
@ -411,7 +304,7 @@ template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(const Texture *_t
}
pixel += sizeof(uintX);
texel++;
}
}
else while (pixel != line_end) {
uint32 alpha = *texel & TEX32_A_MASK;
if (alpha == 0xFF) {
@ -446,9 +339,9 @@ template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(const Texture *_t
pixel += diff;
texel += tex_diff;
}
} else if (_tex->_format == TEX_FMT_NATIVE) {
const uintX *texel = reinterpret_cast<const uintX *>(_tex->getBasePtr(sx, sy));
int tex_diff = _tex->w - w;
} else if (texformat == _format) {
const uintX *texel = reinterpret_cast<const uintX *>(tex->getBasePtr(sx, sy));
int tex_diff = tex->w - w;
while (pixel != end) {
while (pixel != line_end) {
@ -465,23 +358,25 @@ template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(const Texture *_t
pixel += diff;
texel += tex_diff;
}
} else {
error("FadedBlit not supported from %d bpp to %d bpp", texformat.bpp(), _format.bpp());
}
}
//
// void SoftRenderSurface::MaskedBlit(Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend=false)
// void SoftRenderSurface::MaskedBlit(Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend=false)
//
// Desc Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
//
//
template<class uintX> void SoftRenderSurface<uintX>::MaskedBlit(const Texture *_tex, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
template<class uintX> void SoftRenderSurface<uintX>::MaskedBlit(const Graphics::ManagedSurface *tex, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend) {
// Clamp or wrap or return?
if (w > static_cast<int32>(_tex->w))
if (w > static_cast<int32>(tex->w))
return;
// Clamp or wrap or return?
if (h > static_cast<int32>(_tex->h))
if (h > static_cast<int32>(tex->h))
return;
// Clip to window
@ -512,9 +407,11 @@ template<class uintX> void SoftRenderSurface<uintX>::MaskedBlit(const Texture *_
uint32 g = (TEX32_G(col32) * a);
uint32 b = (TEX32_B(col32) * a);
if (_tex->_format == TEX_FMT_STANDARD) {
uint32 *texel = (uint32 *)_tex->getBasePtr(sx, sy);
int tex_diff = _tex->w - w;
int texbpp = tex->rawSurface().format.bpp();
if (texbpp == 32) {
const uint32 *texel = static_cast<const uint32 *>(tex->getBasePtr(sx, sy));
int tex_diff = tex->w - w;
while (pixel != end) {
if (!alpha_blend) {
@ -573,9 +470,9 @@ template<class uintX> void SoftRenderSurface<uintX>::MaskedBlit(const Texture *_
pixel += diff;
texel += tex_diff;
}
} else if (_tex->_format == TEX_FMT_NATIVE) {
const uintX *texel = reinterpret_cast<const uintX *>(_tex->getBasePtr(sx, sy));
int tex_diff = _tex->w - w;
} else if (texbpp == _format.bpp()) {
const uintX *texel = reinterpret_cast<const uintX *>(tex->getBasePtr(sx, sy));
int tex_diff = tex->w - w;
while (pixel != end) {
while (pixel != line_end) {
@ -594,55 +491,12 @@ template<class uintX> void SoftRenderSurface<uintX>::MaskedBlit(const Texture *_
pixel += diff;
texel += tex_diff;
}
} else {
error("unsupported texture format %d bpp", texbpp);
}
}
//
// void SoftRenderSurface::StretchBlit(Texture *, int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh, bool clampedges)
//
// Desc: Blit a region from a Texture, and arbitrarily stretch it to fit the dest region
//
//
template<class uintX> void SoftRenderSurface<uintX>::StretchBlit(const Texture *texture,
int32 sx, int32 sy, int32 sw, int32 sh,
int32 dx, int32 dy, int32 dw, int32 dh,
bool clampedges) {
// Nothing we can do
if ((sh <= 0) || (dh <= 0) || (sw <= 0) || (dw <= 0)) return;
// 1x No scaling needed
if (dw == sw && sh == dh) {
Blit(texture, sw, sy, sw, sh, dx, dy);
return;
}
uint8 *pixel = _pixels + dy * _pitch + dx * sizeof(uintX);
Ultima8Engine::get_instance()->point_scaler.Scale(texture, sx, sy, sw, sh, pixel, dw, dh, _pitch, clampedges);
}
//
// bool SoftRenderSurface::ScalerBlit(Texture *texure, int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh, const Scaler *scaler, bool clampedges)
//
// Desc: Blit a region from a Texture using a scaler
//
//
template<class uintX> bool SoftRenderSurface<uintX>::ScalerBlit(const Texture *texture, int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh, const Scaler *scaler, bool clampedges) {
// Nothing we can do
if ((sh <= 0) || (dh <= 0) || (sw <= 0) || (dw <= 0)) return false;
// 1x No scaling needed (but still do it anyway, could be a filter????)
if (dw == sw && sh == dh) {
Blit(texture, sw, sy, sw, sh, dx, dy);
return true;
}
uint8 *pixel = _pixels + dy * _pitch + dx * sizeof(uintX);
return scaler->Scale(texture, sx, sy, sw, sh, pixel, dw, dh, _pitch, clampedges);
}
//
// void SoftRenderSurface::Paint(Shape*s, uint32 framenum, int32 x, int32 y)
//

View File

@ -35,20 +35,10 @@ namespace Ultima8 {
// Desc: The class for software rendering in Pentagram
//
template<class uintX> class SoftRenderSurface : public BaseSoftRenderSurface {
protected:
// Create Generic surface
SoftRenderSurface(int w, int h, int bpp, int rsft, int gsft, int bsft, int asft);
public:
// Create from a managed surface
SoftRenderSurface(Graphics::ManagedSurface *);
// Create a Generic surface that matches current screen parameters
SoftRenderSurface(int w, int h, uint8 *buf);
// Create a Render to texture surface
SoftRenderSurface(int w, int h);
SoftRenderSurface(Graphics::ManagedSurface *managed);
//
// Surface Filling
@ -109,19 +99,13 @@ public:
//
// Blit a region from a Texture (Alpha == 0 -> skipped)
void Blit(const Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend = false) override;
void Blit(const Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, bool alpha_blend = false) override;
// Blit a region from a Texture with a Colour blend (AlphaTex == 0 -> skipped. AlphaCol32 -> Blend Factors)
void FadedBlit(const Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) override;
void FadedBlit(const Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) override;
// Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
void MaskedBlit(const Texture *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) override;
// Blit a stretched region from a Texture (Alpha == 0 -> skipped)
void StretchBlit(const Texture *, int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh, bool clampedges = false) override;
// Blit a region from a Texture using a scaler
bool ScalerBlit(const Texture *, int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh, const Scaler *, bool clampedges = false) override;
void MaskedBlit(const Graphics::ManagedSurface *, int32 sx, int32 sy, int32 w, int32 h, int32 dx, int32 dy, uint32 col32, bool alpha_blend = false) override;
};
} // End of namespace Ultima8

View File

@ -191,6 +191,8 @@ const int32 neg = (FLIP_CONDITIONAL)?-1:0;
x -= XNEG(frame->_xoff);
y -= frame->_yoff;
assert(_pixels && srcpixels && srcmask);
for (int i = 0; i < height_; i++) {
int line = y + i;

View File

@ -1,152 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/graphics/texture.h"
#include "ultima/ultima8/graphics/texture_bitmap.h"
#include "ultima/ultima8/graphics/texture_targa.h"
#include "ultima/ultima8/graphics/texture_png.h"
#include "ultima/ultima8/graphics/render_surface.h"
namespace Ultima {
namespace Ultima8 {
Texture::Texture() : _format(TEX_FMT_STANDARD), _glTex(0),
_next(nullptr), _wlog2(-1), _hlog2(-1) {
}
//
// Destructor
//
Texture::~Texture() {
}
//
// Helper Macro for texture type detection
//
#define TRY_TYPE(TextureType) \
tex = new TextureType(); \
/* If read failed, delete the texture. */ \
if (!tex->Read(rs)) { \
delete tex; \
tex = nullptr; \
} \
else { \
/* Worked so return it */ \
return tex; \
}
void Texture::create(uint16 width, uint16 height, TextureFormat textureFormat) {
_format = textureFormat;
create(width, height, (_format == TEX_FMT_NATIVE) ? RenderSurface::getPixelFormat() :
Texture::getPixelFormat());
}
//
// Create a texture from a Data Source
// (filename is used to help detection of type)
//
Texture *Texture::Create(Common::SeekableReadStream *rs, const char *filename) {
Texture *tex;
if (filename) {
// Looks like it's a PNG
if (Std::strstr(filename, ".png")) {
TRY_TYPE(TexturePNG);
}
// Looks like it's a BMP
if (Std::strstr(filename, ".bmp")) {
TRY_TYPE(TextureBitmap);
}
// Looks like it's a TGA
if (Std::strstr(filename, ".tga")) {
TRY_TYPE(TextureTarga);
}
}
// Now go through each type 1 by 1
TRY_TYPE(TexturePNG);
TRY_TYPE(TextureBitmap);
TRY_TYPE(TextureTarga);
// Couldn't find it
return nullptr;
}
void Texture::loadSurface(const Graphics::Surface *surf) {
assert(surf->format.bytesPerPixel == 2 || surf->format.bytesPerPixel == 4);
create(surf->w, surf->h, Texture::getPixelFormat());
this->_format = TEX_FMT_STANDARD;
this->_wlog2 = -1;
this->_hlog2 = -1;
// Repack RGBA
uint32 *buffer = (uint32 *)getPixels();
uint32 pixel, i = 0;
byte r, g, b, a;
for (int y = 0; y < surf->h; ++y) {
const byte *srcP = (const byte *)surf->getBasePtr(0, y);
for (int x = 0; x < surf->w; ++x, srcP += surf->format.bytesPerPixel) {
pixel = (surf->format.bytesPerPixel == 2) ? *((const uint16 *)srcP) : *((const uint32 *)srcP);
surf->format.colorToARGB(pixel, a, r, g, b);
buffer[i++] = (r << TEX32_R_SHIFT)
| (g << TEX32_G_SHIFT)
| (b << TEX32_B_SHIFT)
| (a << TEX32_A_SHIFT);
}
}
}
void Texture::loadSurface8Bit(const Graphics::Surface *surf, const byte *pal) {
assert(surf->format.bytesPerPixel == 1 && pal);
create(surf->w, surf->h, Texture::getPixelFormat());
this->_format = TEX_FMT_STANDARD;
this->_wlog2 = -1;
this->_hlog2 = -1;
// Repack RGBA
uint32 *buffer = (uint32 *)getPixels();
uint32 i = 0;
const byte a = 0xff;
for (int y = 0; y < surf->h; ++y) {
const byte *srcP = (const byte *)surf->getBasePtr(0, y);
for (int x = 0; x < surf->w; ++x, srcP++) {
const byte p = *srcP;
const byte r = pal[p*3+0];
const byte g = pal[p*3+1];
const byte b = pal[p*3+2];
buffer[i++] = (r << TEX32_R_SHIFT)
| (g << TEX32_G_SHIFT)
| (b << TEX32_B_SHIFT)
| (a << TEX32_A_SHIFT);
}
}
}
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -59,91 +59,6 @@ namespace Ultima8 {
(((g)>>8)<<TEX32_G_SHIFT)|\
(((b)>>8)<<TEX32_B_SHIFT))
// 64 Bit Texture bit operations
#define TEX64_A_SHIFT 16
#define TEX64_A_MASK 0xFFFF0000
#define TEX64_A_MASK_H 0xFF000000
#define TEX64_G_SHIFT 0
#define TEX64_G_MASK 0x0000FFFF
#define TEX64_G_MASK_H 0x0000FF00
#define TEX64_B_SHIFT 16
#define TEX64_B_MASK 0xFFFF0000
#define TEX64_B_MASK_H 0xFF000000
#define TEX64_R_SHIFT 0
#define TEX64_R_MASK 0x0000FFFF
#define TEX64_R_MASK_H 0x0000FF00
enum TextureFormat {
TEX_FMT_STANDARD = 0, // Standard texture format as defined using Macros above
TEX_FMT_NATIVE = 1 // The native format of the RenderSurface
};
//
// Basic 32 Bit Texture
//
class Texture : public Graphics::ManagedSurface {
public:
uint32 _format;
// Use CalcLOG2s to calculate these (can be -1 which indicates not log2)
int32 _wlog2;
int32 _hlog2;
// For OpenGL
uint32 _glTex;
Texture *_next;
static Graphics::PixelFormat getPixelFormat() {
return Graphics::PixelFormat(4, 8, 8, 8, 8, TEX32_R_SHIFT, TEX32_G_SHIFT, TEX32_B_SHIFT, TEX32_A_SHIFT);
}
Texture();
virtual ~Texture();
void create(uint16 width, uint16 height) override {
Graphics::ManagedSurface::create(width, height);
}
void create(uint16 width, uint16 height, const Graphics::PixelFormat &pixelFormat) override {
Graphics::ManagedSurface::create(width, height, pixelFormat);
}
void create(ManagedSurface &surf, const Common::Rect &bounds) override {
Graphics::ManagedSurface::create(surf, bounds);
}
void create(uint16 width, uint16 height, TextureFormat textureFormat);
// Calc texture log2's
void CalcLOG2s() {
_wlog2 = -1;
_hlog2 = -1;
for (int i = 0; i < 32; i++) {
if (this->w == (1 << i))
_wlog2 = i;
if (this->h == (1 << i))
_hlog2 = i;
}
}
// Create a texture from a Data Source (filename is use to help detection of type)
static Texture *Create(Common::SeekableReadStream *rs, const char *filename = NULL);
// Loads the data from the passed surfcae
void loadSurface(const Graphics::Surface *surf);
// Load data from a passed 8bit surface
void loadSurface8Bit(const Graphics::Surface *surf, const byte *pal);
protected:
// Read from a File. No filetype supported by this class
virtual bool Read(Common::SeekableReadStream *rs) {
return false;
}
};
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -1,47 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/graphics/texture_bitmap.h"
#include "ultima/ultima8/filesys/idata_source.h"
#include "image/bmp.h"
namespace Ultima {
namespace Ultima8 {
//
// Read from a Data Source
//
bool TextureBitmap::Read(Common::SeekableReadStream *rs) {
Image::BitmapDecoder decoder;
if (!decoder.loadStream(*rs))
return false;
const Graphics::Surface *s = decoder.getSurface();
loadSurface(s);
return true;
}
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -1,42 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA8_GRAPHICS_TEXTUREBITMAP_H
#define ULTIMA8_GRAPHICS_TEXTUREBITMAP_H
#include "ultima/ultima8/graphics/texture.h"
namespace Ultima {
namespace Ultima8 {
// container structure for bitmaps .BMP file
struct TextureBitmap : public Texture {
TextureBitmap() : Texture() {}
// False on Error
bool Read(Common::SeekableReadStream *rs) override;
};
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -1,45 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/graphics/texture_png.h"
#include "ultima/ultima8/filesys/idata_source.h"
#include "image/png.h"
#include "graphics/surface.h"
namespace Ultima {
namespace Ultima8 {
bool TexturePNG::Read(Common::SeekableReadStream *rs) {
Image::PNGDecoder decoder;
if (!decoder.loadStream(*rs))
return false;
const Graphics::Surface *s = decoder.getSurface();
loadSurface(s);
return true;
}
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -1,41 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA8_GRAPHICS_TEXTUREPNG_H
#define ULTIMA8_GRAPHICS_TEXTUREPNG_H
#include "ultima/ultima8/graphics/texture.h"
namespace Ultima {
namespace Ultima8 {
// container structure for graphics read from a PNG file
struct TexturePNG : public Texture {
TexturePNG() : Texture() {}
// False on Error
bool Read(Common::SeekableReadStream *rs) override;
};
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -1,44 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/graphics/texture_targa.h"
#include "ultima/ultima8/filesys/idata_source.h"
#include "image/tga.h"
namespace Ultima {
namespace Ultima8 {
bool TextureTarga::Read(Common::SeekableReadStream *rs) {
Image::TGADecoder decoder;
if (!decoder.loadStream(*rs))
return false;
const Graphics::Surface *s = decoder.getSurface();
loadSurface(s);
return true;
}
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -1,44 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA8_GRAPHICS_TEXTURETARGA_H
#define ULTIMA8_GRAPHICS_TEXTURETARGA_H
#include "ultima/ultima8/graphics/texture.h"
namespace Ultima {
namespace Ultima8 {
struct TGA;
// container structure for bitmaps .BMP file
struct TextureTarga : public Texture {
TextureTarga() : Texture() {}
// False on Error
bool Read(Common::SeekableReadStream *rs) override;
};
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -172,7 +172,6 @@ void CreditsGump::run() {
if (_state == CS_PLAYING && available <= 160) {
// time to render next block
_scroll[nextblock]->Fill32(0xFF000000, 0, 0, 256, 200);
// _scroll[nextblock]->Fill32(0xFFFFFFFF,0,0,256,5); // block marker
_scrollHeight[nextblock] = 0;
@ -352,22 +351,20 @@ void CreditsGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
if (_title)
_title->draw(surf, 64, 34);
Texture *tex = _scroll[_currentSurface]->GetSurfaceAsTexture();
int h = _scrollHeight[_currentSurface] - _currentY;
if (h > 156) h = 156;
if (h > 0)
surf->Blit(tex, 0, _currentY, 256, h, 32, 44);
surf->Blit(_scroll[_currentSurface]->getRawSurface(), 0, _currentY, 256, h, 32, 44);
int y = h;
for (int i = 1; i < 4; i++) {
if (h == 156) break;
int s = (_currentSurface + i) % 4;
tex = _scroll[s]->GetSurfaceAsTexture();
h = _scrollHeight[s];
if (h > 156 - y) h = 156 - y;
if (h > 0)
surf->Blit(tex, 0, 0, 256, h, 32, 44 + y);
surf->Blit(_scroll[s]->getRawSurface(), 0, 0, 256, h, 32, 44 + y);
y += h;
}
}

View File

@ -30,7 +30,6 @@
#include "ultima/ultima8/gumps/gump_notify_process.h"
#include "ultima/ultima8/kernel/kernel.h"
#include "ultima/ultima8/kernel/object_manager.h"
#include "ultima/ultima8/gumps/scaler_gump.h"
#include "ultima/ultima8/ultima8.h"
namespace Ultima {

View File

@ -100,15 +100,13 @@ void InverterGump::PaintChildren(RenderSurface *surf, int32 lerp_factor, bool sc
DesktopGump::PaintChildren(_buffer, lerp_factor, scaled);
Texture *tex = _buffer->GetSurfaceAsTexture();
// now invert-blit _buffer to screen
int t = (state * height) / 0x10000;
for (int i = 0; i < height; ++i) {
int src = getLine(getIndex(i, height / 2) + t, height / 2);
// pout << src << " -> " << i << Std::endl;
surf->Blit(tex, 0, src, width, 1, 0, i);
surf->Blit(_buffer->getRawSurface(), 0, src, width, 1, 0, i);
}
}

View File

@ -62,7 +62,7 @@ void ItemRelativeGump::MoveOnScreen() {
_x = 0;
_y = 0;
// get rectangle that gump occupies in scalerGump's coordinate space
// get rectangle that gump occupies in desktops's coordinate space
int32 left, right, top, bottom;
left = -_dims.left;
right = left + _dims.width();

View File

@ -38,12 +38,14 @@ namespace Ultima8 {
DEFINE_RUNTIME_CLASSTYPE_CODE(MiniMapGump)
static const int MINMAPGUMP_SCALE = 8;
MiniMapGump::MiniMapGump(int x, int y) :
Gump(x, y, MAP_NUM_CHUNKS * 2 + 2, MAP_NUM_CHUNKS * 2 + 2, 0,
FLAG_DRAGGABLE, LAYER_NORMAL), _minimap(), _lastMapNum(0) {
_minimap._format = TEX_FMT_NATIVE;
_minimap.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
TEX_FMT_NATIVE);
_minimap = Graphics::ManagedSurface((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
RenderSurface::getPixelFormat());
}
MiniMapGump::MiniMapGump() : Gump() , _lastMapNum(0){
@ -62,12 +64,12 @@ void MiniMapGump::setPixelAt(int x, int y, uint32 pixel) {
}
}
uint32 MiniMapGump::getPixelAt(int x, int y) {
uint32 MiniMapGump::getPixelAt(int x, int y) const {
if (_minimap.format.bytesPerPixel == 2) {
uint16 *buf = (uint16 *)_minimap.getBasePtr(x, y);
const uint16 *buf = (const uint16 *)_minimap.getBasePtr(x, y);
return *buf;
} else {
uint32 *buf = (uint32 *)_minimap.getBasePtr(x, y);
const uint32 *buf = (const uint32 *)_minimap.getBasePtr(x, y);
return *buf;
}
}
@ -82,11 +84,13 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
_lastMapNum = currentmap->getNum();
}
// Draw the yellow border
surf->Fill32(0xFFFFAF00, 0, 0, MAP_NUM_CHUNKS * 2 + 3, 1);
surf->Fill32(0xFFFFAF00, 0, 1, 1, MAP_NUM_CHUNKS * 2 + 1);
surf->Fill32(0xFFFFAF00, 1, MAP_NUM_CHUNKS * 2 + 1, MAP_NUM_CHUNKS * 2 + 1, 1);
surf->Fill32(0xFFFFAF00, MAP_NUM_CHUNKS * 2 + 1, 1, 1, MAP_NUM_CHUNKS * 2 + 1);
// Draw into the map surface
for (int yv = 0; yv < MAP_NUM_CHUNKS; yv++) {
for (int xv = 0; xv < MAP_NUM_CHUNKS; xv++) {
if (currentmap->isChunkFast(xv, yv)) {
@ -204,7 +208,7 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
return false;
_lastMapNum = 0;
_minimap.create(MAP_NUM_CHUNKS * MINMAPGUMP_SCALE, MAP_NUM_CHUNKS * MINMAPGUMP_SCALE, TEX_FMT_NATIVE);
_minimap.create(MAP_NUM_CHUNKS * MINMAPGUMP_SCALE, MAP_NUM_CHUNKS * MINMAPGUMP_SCALE, RenderSurface::getPixelFormat());
return true;
}

View File

@ -31,14 +31,12 @@
namespace Ultima {
namespace Ultima8 {
#define MINMAPGUMP_SCALE 8
class MiniMapGump : public Gump {
private:
Texture _minimap;
Graphics::ManagedSurface _minimap;
unsigned int _lastMapNum;
uint32 getPixelAt(int x, int y);
uint32 getPixelAt(int x, int y) const;
void setPixelAt(int x, int y, uint32 pixel);
uint32 sampleAtPoint(int x, int y, CurrentMap *map);
public:

View File

@ -1,249 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/gumps/scaler_gump.h"
#include "ultima/ultima8/graphics/render_surface.h"
#include "ultima/ultima8/graphics/texture.h"
#include "ultima/ultima8/graphics/scaler.h"
#include "ultima/ultima8/conf/setting_manager.h"
#include "ultima/ultima8/ultima8.h"
namespace Ultima {
namespace Ultima8 {
DEFINE_RUNTIME_CLASSTYPE_CODE(ScalerGump)
ScalerGump::ScalerGump(int32 x, int32 y, int32 width, int32 height) :
DesktopGump(x, y, width, height),
_swidth1(width), _sheight1(height),
_scaler1(nullptr), _buffer1(nullptr),
_swidth2(width), _sheight2(height),
_scaler2(nullptr), _buffer2(nullptr),
_width(width), _height(height) {
setupScaling();
if (_buffer1)
_buffer1->Fill32(0, 0, 0, _dims.width(), _dims.height());
}
ScalerGump::~ScalerGump() {
FORGET_OBJECT(_buffer1);
FORGET_OBJECT(_buffer2);
}
void ScalerGump::Paint(RenderSurface *surf, int32 lerp_factor, bool scaled) {
// Skip the clipping rect/origin setting, since they will already be set
// correctly by our parent.
// (Or maybe I'm just to lazy to figure out the correct coordinates
// to use to compensate for the flipping... -wjp :-) )
// Don't paint if hidden
if (IsHidden()) return;
// No scaling or filtering
if (!_buffer1) {
PaintChildren(surf, lerp_factor, scaled);
return;
}
// Render to texture
_buffer1->BeginPainting();
PaintChildren(_buffer1, lerp_factor, true);
_buffer1->EndPainting();
if (!_buffer2) {
DoScalerBlit(_buffer1->GetSurfaceAsTexture(), _swidth1, _sheight1, surf, _width, _height, _scaler1);
} else {
_buffer2->BeginPainting();
DoScalerBlit(_buffer1->GetSurfaceAsTexture(), _swidth1, _sheight1, _buffer2, _swidth2, _sheight2, _scaler1);
_buffer2->EndPainting();
DoScalerBlit(_buffer2->GetSurfaceAsTexture(), _swidth2, _sheight2, surf, _width, _height, _scaler2);
}
int32 scalex = (_width << 16) / _swidth1;
int32 scaley = (_height << 16) / _sheight1;
// Iterate all children
Std::list<Gump *>::reverse_iterator it = _children.rbegin();
Std::list<Gump *>::reverse_iterator end = _children.rend();
while (it != end) {
Gump *g = *it;
// Paint if not closing
if (!g->IsClosing())
g->PaintCompositing(surf, lerp_factor, scalex, scaley);
++it;
}
}
void ScalerGump::DoScalerBlit(Texture *src, int swidth, int sheight, RenderSurface *dest, int dwidth, int dheight, const Scaler *scaler) {
bool ok = true;
// Cheap and nasty method to use a 2x scaler to do a 2.4x scale vertically
if (dwidth == 640 && swidth == 320 && dheight == 480 && sheight == 200 && !scaler->ScaleArbitrary()) {
ok = dest->ScalerBlit(src, 0, 0, swidth, 1, 0, 0, dwidth, 2, scaler);
int d = 1, s = 0;
while (d < 468 && ok) {
ok = dest->ScalerBlit(src, 0, s, swidth, 3, 0, d, dwidth, 6, scaler);
d += 5;
s += 2;
if (!ok) break;
ok = dest->ScalerBlit(src, 0, s, swidth, 4, 0, d, dwidth, 8, scaler);
d += 7;
s += 3;
}
while (d < 478 && ok) {
ok = dest->ScalerBlit(src, 0, s, swidth, 3, 0, d, dwidth, 6, scaler);
d += 5;
s += 2;
}
} else {
ok = dest->ScalerBlit(src, 0, 0, swidth, sheight, 0, 0, dwidth, dheight, scaler);
}
if (!ok) {
dest->StretchBlit(src, 0, 0, swidth, sheight, 0, 0, dwidth, dheight);
}
}
// Convert a parent relative point to a gump point
void ScalerGump::ParentToGump(int32 &px, int32 &py, PointRoundDir r) {
px -= _x;
px *= _dims.width();
if (px < 0 && r == ROUND_TOPLEFT) px -= (_width - 1);
if (px > 0 && r == ROUND_BOTTOMRIGHT) px += (_width - 1);
px /= _width;
py -= _y;
py *= _dims.height();
if (py < 0 && r == ROUND_TOPLEFT) py -= (_height - 1);
if (py > 0 && r == ROUND_BOTTOMRIGHT) py += (_height - 1);
py /= _height;
}
// Convert a gump point to parent relative point
void ScalerGump::GumpToParent(int32 &gx, int32 &gy, PointRoundDir r) {
gx *= _width;
if (gx < 0 && r == ROUND_TOPLEFT) gx -= (_dims.width() - 1);
if (gx > 0 && r == ROUND_BOTTOMRIGHT) gx += (_dims.width() - 1);
gx /= _dims.width();
gx += _x;
gy *= _height;
if (gy < 0 && r == ROUND_TOPLEFT) gy -= (_dims.height() - 1);
if (gy > 0 && r == ROUND_BOTTOMRIGHT) gy += (_dims.height() - 1);
gy /= _dims.height();
gy += _y;
}
void ScalerGump::RenderSurfaceChanged() {
// Resize the gump to match the RenderSurface
Rect new_dims;
_parent->GetDims(new_dims);
_width = new_dims.width();
_height = new_dims.height();
setupScaling();
Gump::RenderSurfaceChanged();
}
void ScalerGump::setupScaling() {
FORGET_OBJECT(_buffer1);
FORGET_OBJECT(_buffer2);
if (CoreApp::get_instance()->getGameInfo() && GAME_IS_U8) {
_swidth1 = Ultima8Engine::U8_DEFAULT_SCREEN_WIDTH;
_sheight1 = Ultima8Engine::U8_DEFAULT_SCREEN_HEIGHT;
} else {
_swidth1 = Ultima8Engine::CRUSADER_DEFAULT_SCREEN_WIDTH;
_sheight1 = Ultima8Engine::CRUSADER_DEFAULT_SCREEN_HEIGHT;
}
_swidth2 = 0;
_sheight2 = 0;
const Scaler *point = &Ultima8Engine::get_instance()->point_scaler;
_scaler1 = _scaler2 = point;
if (_swidth1 < 0) _swidth1 = -_swidth1;
else if (_swidth1 == 0) _swidth1 = _width;
else if (_swidth1 < 100) _swidth1 = _width / _swidth1;
if (_sheight1 < 0) _sheight1 = -_sheight1;
else if (_sheight1 == 0) _sheight1 = _height;
else if (_sheight1 < 100) _sheight1 = _height / _sheight1;
if (_swidth2 < 0) _swidth2 = -_swidth2;
else if (_swidth2 != 0 && _swidth2 < 100) _swidth2 = _width / _swidth2;
if (_sheight2 < 0) _sheight2 = -_sheight2;
else if (_sheight2 != 0 && _sheight2 < 100) _sheight2 = _height / _sheight2;
_dims.setWidth(_swidth1);
_dims.setHeight(_sheight1);
// We don't care, we are not going to support filters, at least not at the moment
if (_swidth1 == _width && _sheight1 == _height) return;
_buffer1 = RenderSurface::CreateSecondaryRenderSurface(_swidth1, _sheight1);
// _scaler2's factor isn't set so auto detect
if (_swidth2 == 0 || _sheight2 == 0) {
// scaler 1 is arbitrary so _scaler2 not required
if (_scaler1->ScaleArbitrary()) return;
_swidth2 = _swidth1 * 32;
_sheight2 = _sheight1 * 32;
for (int i = 31; i >= 0; i--) {
if (_scaler1->ScaleBits() & (1 << i)) {
if (_swidth2 > _width || _sheight2 > _height) {
_swidth2 = _swidth1 * i;
_sheight2 = _sheight1 * i;
}
}
}
}
// _scaler2 is required
if (_swidth2 != _width || _sheight2 != _height) {
// Well almost, in this situation we code in DoScalerBlit to do this for us
// _scaler2 not required
if (_width == 640 && _height == 480 &&
_swidth2 == 640 && _sheight2 == 400 &&
_swidth1 == 320 && _sheight1 == 200) {
return;
}
_buffer2 = RenderSurface::CreateSecondaryRenderSurface(_swidth2, _sheight2);
}
}
} // End of namespace Ultima8
} // End of namespace Ultima

View File

@ -1,91 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA8_GUMPS_SCALERGUMP_H
#define ULTIMA8_GUMPS_SCALERGUMP_H
#include "ultima/ultima8/gumps/desktop_gump.h"
#include "ultima/shared/std/containers.h"
#include "ultima/ultima8/misc/p_dynamic_cast.h"
namespace Ultima {
namespace Ultima8 {
class RenderSurface;
class Texture;
class Scaler;
/**
* A virtual gump which scales the contents for display. Mostly unused since import to scummvm.
* TODO: Look into removing this entirely.
*/
class ScalerGump : public DesktopGump {
public:
ENABLE_RUNTIME_CLASSTYPE()
//! ScalerGump constructor
//! \param x x coordinate of our top-left corner in parent
//! \param y y coordinate
//! \param width width after scaling (usually screenwidth)
//! \param height height after scaling (usually screenheight)
//! \param swidth1 width before scaling (usually game-width)
//! \param sheight1 height before scaling (usually game-height)
//! \param scaler1 scaler to use
ScalerGump(int32 x, int32 y, int32 width, int32 height);
~ScalerGump() override;
void Paint(RenderSurface *surf, int32 lerp_factor, bool scaled) override;
void RenderSurfaceChanged() override;
void ParentToGump(int32 &px, int32 &py,
PointRoundDir r = ROUND_TOPLEFT) override;
void GumpToParent(int32 &gx, int32 &gy,
PointRoundDir r = ROUND_TOPLEFT) override;
void GetScaledSize(int32 &sw, int32 &sh) const {
sw = _swidth1;
sh = _sheight1;
}
protected:
int _swidth1;
int _sheight1;
const Scaler *_scaler1;
RenderSurface *_buffer1;
int _swidth2;
int _sheight2;
const Scaler *_scaler2;
RenderSurface *_buffer2;
int32 _width;
int32 _height;
private:
void setupScaling();
void DoScalerBlit(Texture *src, int swidth, int sheight, RenderSurface *dest, int dwidth, int dheight, const Scaler *scaler);
};
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -40,7 +40,7 @@ namespace Ultima8 {
Mouse *Mouse::_instance = nullptr;
Mouse::Mouse() : _flashingCursorTime(0), _mouseOverGump(0), _defaultMouse(nullptr),
Mouse::Mouse() : _flashingCursorTime(0), _mouseOverGump(0),
_dragging(DRAG_NOT), _dragging_objId(0), _draggingItem_startGump(0),
_draggingItem_lastGump(0) {
_instance = this;
@ -51,14 +51,6 @@ Mouse::~Mouse() {
}
void Mouse::setup() {
FileSystem *filesys = FileSystem::get_instance();
Common::SeekableReadStream *dm = filesys->ReadFile("@data/mouse.tga");
_defaultMouse = dm ? Texture::Create(dm, "@data/mouse.tga") : 0;
if (!_defaultMouse)
error("Unable to load '@data/mouse.tga'");
delete dm;
pushMouseCursor();
}
@ -547,18 +539,15 @@ void Mouse::paint() {
RenderSurface *screen = Ultima8Engine::get_instance()->getRenderScreen();
GameData *gamedata = GameData::get_instance();
if (gamedata) {
Shape *mouse = gamedata->getMouse();
if (mouse) {
int frame = getMouseFrame();
if (frame >= 0) {
screen->Paint(mouse, frame, _mousePos.x, _mousePos.y, true);
} else if (frame == -2)
screen->Blit(_defaultMouse, 0, 0, _defaultMouse->w, _defaultMouse->h, _mousePos.x, _mousePos.y);
if (!gamedata)
return;
const Shape *mouse = gamedata->getMouse();
if (mouse) {
int frame = getMouseFrame();
if (frame >= 0) {
screen->Paint(mouse, frame, _mousePos.x, _mousePos.y, true);
}
} else {
if (getMouseFrame() != -1)
screen->Blit(_defaultMouse, 0, 0, _defaultMouse->w, _defaultMouse->h, _mousePos.x, _mousePos.y);
}
}

View File

@ -104,7 +104,6 @@ public:
private:
static Mouse *_instance;
Common::Stack<MouseCursor> _cursors;
Texture *_defaultMouse; //!< Default Pentagram mouse for when there is no GameData
/**
* Time mouse started flashing, or 0

View File

@ -30,6 +30,7 @@
#include "ultima/ultima8/filesys/file_system.h"
#include "ultima/ultima8/filesys/raw_archive.h"
#include "ultima/ultima8/graphics/inverter_process.h"
#include "ultima/ultima8/graphics/render_surface.h"
#include "ultima/ultima8/gumps/fast_area_vis_gump.h"
#include "ultima/ultima8/gumps/game_map_gump.h"
#include "ultima/ultima8/gumps/minimap_gump.h"
@ -828,9 +829,6 @@ bool Debugger::cmdDumpMap(int argc, const char **argv) {
RenderSurface *s = RenderSurface::CreateSecondaryRenderSurface(bwidth,
bheight);
Texture *t = s->GetSurfaceAsTexture();
//t->clear();
debugPrintf("Rendering map...\n");
// Now render the map
@ -878,9 +876,9 @@ bool Debugger::cmdDumpMap(int argc, const char **argv) {
bool result = dumpFile.open(filename);
if (result) {
#ifdef USE_PNG
result = Image::writePNG(dumpFile, *t);
result = Image::writePNG(dumpFile, *(s->getRawSurface()));
#else
result = Image::writeBMP(dumpFile, *t);
result = Image::writeBMP(dumpFile, *(s->getRawSurface()));
#endif
}

View File

@ -1,111 +0,0 @@
/* 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.
*
*/
//
// memset_n is a set of optimized functions for filling buffers of
// 16 and 32 bit integers
//
#ifndef ULTIMA8_MISC_MEMSET_N_H
#define ULTIMA8_MISC_MEMSET_N_H
namespace Ultima {
namespace Ultima8 {
//
// Generic memset_32
//
// Can be used by all
//
inline void memset_32_aligned(void *buf, uint32 val, uint32 dwords) {
do {
*reinterpret_cast<uint32 *>(buf) = val;
buf = (reinterpret_cast<uint32 *>(buf)) + 1;
} while (--dwords);
}
//
// memset_32
//
// Can be used by all
//
inline void memset_32(void *buf, uint32 val, uint32 dwords) {
// Fisrly we should dword Align it
int align = 0;
if (reinterpret_cast<uintptr>(buf) & 3) {
align = 4;
dwords--;
// Ok, shift along by 1 byte
if ((reinterpret_cast<uintptr>(buf) & 1)) {
*reinterpret_cast<uint8 *>(buf) = static_cast<uint8>(val & 0xFF);
buf = (reinterpret_cast<uint8 *>(buf)) + 1;
val = ((val & 0xFF) << 24) | ((val & 0xFFFFFF00) >> 8);
align --;
}
// Ok, shift along by 2 bytes
if ((reinterpret_cast<uintptr>(buf) & 2)) {
*reinterpret_cast<uint16 *>(buf) = static_cast<uint16>(val & 0xFFFF);
buf = (reinterpret_cast<uint16 *>(buf)) + 1;
val = ((val & 0xFFFF) << 16) | ((val & 0xFFFF0000) >> 16);
align -= 2;
}
}
// Fill Aligned
if (dwords) memset_32_aligned(buf, val, dwords);
// Do the unaligned data
if (align) {
buf = (reinterpret_cast<uint8 *>(buf)) + dwords * 4;
// Ok, shift along by 1 byte
if (align == 1) {
*reinterpret_cast<uint8 *>(buf) = static_cast<uint8>(val & 0xFF);
}
// Ok, shift along by 2 bytes
else {
*reinterpret_cast<uint16 *>(buf) = static_cast<uint16>(val & 0xFFFF);
// Ok, shift along by another byte
if (align & 1) *(reinterpret_cast<uint8 *>(buf) + 2) = static_cast<uint8>((val >> 16) & 0xFF);
}
}
}
//
// memset_16
//
// Can be used by all
//
inline void memset_16(void *buf, int32 val, uint32 words) {
// Use memset_32
if (words > 1) memset_32(buf, val | val << 16, words>>1);
// Final word
if (words & 1) *(reinterpret_cast<uint16 *>(buf) + (words - 1)) = static_cast<uint16>(val & 0xFFFF);
}
} // End of namespace Ultima8
} // End of namespace Ultima
#endif

View File

@ -42,7 +42,6 @@
#include "ultima/ultima8/graphics/fonts/font_manager.h"
#include "ultima/ultima8/graphics/render_surface.h"
#include "ultima/ultima8/graphics/texture.h"
#include "ultima/ultima8/graphics/fonts/fixed_width_font.h"
#include "ultima/ultima8/graphics/palette_manager.h"
#include "ultima/ultima8/graphics/palette.h"
#include "ultima/ultima8/games/game_data.h"
@ -56,7 +55,6 @@
#include "ultima/ultima8/gumps/desktop_gump.h"
#include "ultima/ultima8/gumps/game_map_gump.h"
#include "ultima/ultima8/gumps/inverter_gump.h"
#include "ultima/ultima8/gumps/scaler_gump.h"
#include "ultima/ultima8/gumps/fast_area_vis_gump.h"
#include "ultima/ultima8/gumps/minimap_gump.h"
#include "ultima/ultima8/gumps/quit_gump.h"
@ -157,9 +155,8 @@ Ultima8Engine::Ultima8Engine(OSystem *syst, const Ultima::UltimaGameDescription
_frameSkip(false), _frameLimit(true), _interpolate(true), _animationRate(100),
_avatarInStasis(false), _paintEditorItems(false), _inversion(0), _painting(false),
_showTouching(false), _timeOffset(0), _hasCheated(false), _cheatsEnabled(false),
_ttfOverrides(false), _audioMixer(0), _scalerGump(nullptr),
_inverterGump(nullptr), _lerpFactor(256), _inBetweenFrame(false),
_unkCrusaderFlag(false), _moveKeyFrame(0) {
_ttfOverrides(false), _audioMixer(0), _inverterGump(nullptr), _lerpFactor(256),
_inBetweenFrame(false), _unkCrusaderFlag(false), _moveKeyFrame(0) {
_application = this;
}
@ -439,7 +436,6 @@ void Ultima8Engine::shutdownGame(bool reloading) {
_desktopGump = nullptr;
_gameMapGump = nullptr;
_scalerGump = nullptr;
_inverterGump = nullptr;
_timeOffset = -(int32)Kernel::get_instance()->getFrameNum();
@ -461,15 +457,8 @@ void Ultima8Engine::shutdownGame(bool reloading) {
_desktopGump->MakeFocus();
if (GAME_IS_U8) {
debugN(MM_INFO, "Creating _scalerGump...\n");
_scalerGump = new ScalerGump(0, 0, dims.width(), dims.height());
_scalerGump->InitGump(0);
Rect scaled_dims;
_scalerGump->GetDims(scaled_dims);
debugN(MM_INFO, "Creating Inverter...\n");
_inverterGump = new InverterGump(0, 0, scaled_dims.width(), scaled_dims.height());
_inverterGump = new InverterGump(0, 0, dims.width(), dims.height());
_inverterGump->InitGump(0);
}
}
@ -690,33 +679,12 @@ void Ultima8Engine::GraphicSysInit() {
debugN(MM_INFO, "Loading Default Mouse Cursor...\n");
_mouse->setup();
Std::string alt_confont;
bool confont_loaded = false;
if (_settingMan->get("console_font", alt_confont)) {
debugN(MM_INFO, "Alternate console font found...\n");
confont_loaded = LoadConsoleFont(alt_confont);
}
if (!confont_loaded) {
debugN(MM_INFO, "Loading default console font...\n");
if (!LoadConsoleFont("@data/fixedfont.ini")) {
error("Failed to load console font. Exiting");
}
}
_desktopGump = new DesktopGump(0, 0, width, height);
_desktopGump->InitGump(0);
_desktopGump->MakeFocus();
if (GAME_IS_U8) {
_scalerGump = new ScalerGump(0, 0, width, height);
_scalerGump->InitGump(0);
Rect scaled_dims;
_scalerGump->GetDims(scaled_dims);
_inverterGump = new InverterGump(0, 0, scaled_dims.width(), scaled_dims.height());
_inverterGump = new InverterGump(0, 0, width, height);
_inverterGump->InitGump(0);
}
@ -757,19 +725,6 @@ void Ultima8Engine::changeVideoMode(int width, int height) {
GraphicSysInit();
}
bool Ultima8Engine::LoadConsoleFont(Std::string confontini) {
// try to load the file
debugN(MM_INFO, "Loading console font config: %s... ", confontini.c_str());
if (_configFileMan->readConfigFile(confontini, "confont", true))
pout << "Ok" << Std::endl;
else {
pout << "Failed" << Std::endl;
return false;
}
return true;
}
void Ultima8Engine::enterTextMode(Gump *gump) {
if (!_textModes.empty()) {
_textModes.remove(gump->getObjId());
@ -1075,7 +1030,6 @@ void Ultima8Engine::resetEngine() {
// Reset thet gumps
_desktopGump = nullptr;
_gameMapGump = nullptr;
_scalerGump = nullptr;
_inverterGump = nullptr;
_textModes.clear();
@ -1104,34 +1058,22 @@ void Ultima8Engine::setupCoreGumps() {
_desktopGump->MakeFocus();
if (GAME_IS_U8) {
debugN(MM_INFO, "Creating ScalerGump...\n");
_scalerGump = new ScalerGump(0, 0, dims.width(), dims.height());
_scalerGump->InitGump(0);
Rect scaled_dims;
_scalerGump->GetDims(scaled_dims);
debugN(MM_INFO, "Creating Inverter...\n");
_inverterGump = new InverterGump(0, 0, scaled_dims.width(), scaled_dims.height());
_inverterGump = new InverterGump(0, 0, dims.width(), dims.height());
_inverterGump->InitGump(0);
debugN(MM_INFO, "Creating GameMapGump...\n");
_gameMapGump = new GameMapGump(0, 0, scaled_dims.width(), scaled_dims.height());
_gameMapGump->InitGump(0);
} else {
_gameMapGump = new GameMapGump(0, 0, dims.width(), dims.height());
_gameMapGump->InitGump(0);
}
debugN(MM_INFO, "Creating GameMapGump...\n");
_gameMapGump = new GameMapGump(0, 0, dims.width(), dims.height());
_gameMapGump->InitGump(0);
// TODO: clean this up
if (GAME_IS_U8) {
assert(_desktopGump->getObjId() == 256);
assert(_scalerGump->getObjId() == 257);
assert(_inverterGump->getObjId() == 258);
assert(_gameMapGump->getObjId() == 259);
assert(_inverterGump->getObjId() == 257);
assert(_gameMapGump->getObjId() == 258);
}
for (uint16 i = 261; i < 384; ++i)
for (uint16 i = 259; i < 384; ++i)
_objectManager->reserveObjId(i);
}
@ -1374,7 +1316,7 @@ void Ultima8Engine::addGump(Gump *gump) {
assert(_desktopGump);
if (dynamic_cast<ShapeViewerGump *>(gump) || dynamic_cast<MiniMapGump *>(gump) ||
dynamic_cast<ScalerGump *>(gump) || dynamic_cast<MessageBoxGump *>(gump)// ||
dynamic_cast<MessageBoxGump *>(gump)// ||
//(_ttfOverrides && (dynamic_cast<BarkGump *>(gump) ||
// dynamic_cast<AskGump *>(gump)))
) {
@ -1385,13 +1327,10 @@ void Ultima8Engine::addGump(Gump *gump) {
else
_desktopGump->AddChild(gump);
} else if (dynamic_cast<InverterGump *>(gump)) {
_scalerGump->AddChild(gump);
_desktopGump->AddChild(gump);
} else if (dynamic_cast<DesktopGump *>(gump)) {
} else {
if (GAME_IS_U8)
_scalerGump->AddChild(gump);
else
_desktopGump->AddChild(gump);
_desktopGump->AddChild(gump);
}
}

View File

@ -43,7 +43,6 @@
#include "ultima/ultima8/kernel/core_app.h"
#include "ultima/ultima8/kernel/mouse.h"
#include "ultima/ultima8/misc/p_dynamic_cast.h"
#include "ultima/ultima8/graphics/point_scaler.h"
#include "common/events.h"
namespace Ultima {
@ -56,7 +55,6 @@ class Game;
class Gump;
class GameMapGump;
class MenuGump;
class ScalerGump;
class InverterGump;
class RenderSurface;
class PaletteManager;
@ -96,7 +94,6 @@ private:
Gump *_desktopGump;
GameMapGump *_gameMapGump;
ScalerGump *_scalerGump;
InverterGump *_inverterGump;
AvatarMoverProcess *_avatarMoverProcess;
@ -155,7 +152,6 @@ private:
// called depending upon command line arguments
void GraphicSysInit(); // starts/restarts the graphics subsystem
bool LoadConsoleFont(Std::string confontini); // loads the console font
void handleDelayedEvents();
protected:
@ -168,8 +164,7 @@ protected:
* Returns the data archive folder and version that's required
*/
bool isDataRequired(Common::String &folder, int &majorVersion, int &minorVersion) override;
public:
PointScaler point_scaler;
public:
Ultima8Engine(OSystem *syst, const Ultima::UltimaGameDescription *gameDesc);
~Ultima8Engine() override;

View File

@ -1,95 +0,0 @@
#include <cxxtest/TestSuite.h>
#include "engines/ultima/ultima8/misc/memset_n.h"
/**
* Test suite for the functions in engines/ultima/ultima8/misc/memset_n.h
*/
class U8MemsetTestSuite : public CxxTest::TestSuite {
static const uint32 VAL32 = 0xDEADBEEF;
static const uint32 VAL16 = 0xFEED;
uint8 buffer[256];
public:
U8MemsetTestSuite() {
}
static uint32 uint32val(const uint8 *p) {
return *reinterpret_cast<const uint32 *>(p);
}
static uint16 uint16val(const uint8 *p) {
return *reinterpret_cast<const uint16 *>(p);
}
void clear_buffer() {
memset(buffer, 0, 256);
}
void test_memset_32() {
// Pointer with some padding so we can make sure it does the right
// thing at start and end of memory block
uint8 *b = buffer + 16;
// Check a few alignments to make sure it does the right thing
// Starting alignment is not important as we cycle through them all
for (int i = 0; i < 10; i++) {
b++;
clear_buffer();
Ultima::Ultima8::memset_32(b, VAL32, 1);
TS_ASSERT_EQUALS(uint32val(b), VAL32);
TS_ASSERT_EQUALS(uint32val(b+4), 0);
TS_ASSERT_EQUALS(uint32val(b-4), 0);
clear_buffer();
Ultima::Ultima8::memset_32(b, VAL32, 2);
TS_ASSERT_EQUALS(uint32val(b), VAL32);
TS_ASSERT_EQUALS(uint32val(b+4), VAL32);
TS_ASSERT_EQUALS(uint32val(b+8), 0);
TS_ASSERT_EQUALS(uint32val(b-4), 0);
}
}
void test_memset_16() {
// Pointer with some padding so we can make sure it does the right
// thing at start and end of memory block
uint8 *b = buffer + 16;
// Check a few alignments to make sure it does the right thing
// Starting alignment is not important as we cycle through them all
for (int i = 0; i < 10; i++) {
b++;
clear_buffer();
Ultima::Ultima8::memset_16(b, VAL16, 1);
TS_ASSERT_EQUALS(uint16val(b), VAL16);
TS_ASSERT_EQUALS(uint16val(b+2), 0);
TS_ASSERT_EQUALS(uint16val(b-2), 0);
clear_buffer();
Ultima::Ultima8::memset_16(b, VAL16, 2);
TS_ASSERT_EQUALS(uint16val(b), VAL16);
TS_ASSERT_EQUALS(uint16val(b+2), VAL16);
TS_ASSERT_EQUALS(uint16val(b+4), 0);
TS_ASSERT_EQUALS(uint16val(b-2), 0);
clear_buffer();
Ultima::Ultima8::memset_16(b, VAL16, 3);
TS_ASSERT_EQUALS(uint16val(b), VAL16);
TS_ASSERT_EQUALS(uint16val(b+2), VAL16);
TS_ASSERT_EQUALS(uint16val(b+4), VAL16);
TS_ASSERT_EQUALS(uint16val(b+6), 0);
TS_ASSERT_EQUALS(uint16val(b-2), 0);
clear_buffer();
Ultima::Ultima8::memset_16(b, VAL16, 4);
TS_ASSERT_EQUALS(uint16val(b), VAL16);
TS_ASSERT_EQUALS(uint16val(b+2), VAL16);
TS_ASSERT_EQUALS(uint16val(b+4), VAL16);
TS_ASSERT_EQUALS(uint16val(b+6), VAL16);
TS_ASSERT_EQUALS(uint16val(b+8), 0);
TS_ASSERT_EQUALS(uint16val(b-2), 0);
}
}
};