aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/gfx/gfx_driver.cpp66
-rw-r--r--engines/sci/gfx/gfx_driver.h7
-rw-r--r--engines/sci/gfx/gfx_pixmap_scale.cpp5
-rw-r--r--engines/sci/gfx/gfx_resmgr.cpp3
-rw-r--r--engines/sci/gfx/gfx_system.h3
-rw-r--r--engines/sci/gfx/gfx_tools.cpp9
-rw-r--r--engines/sci/gfx/operations.cpp15
-rw-r--r--engines/sci/gfx/operations.h8
-rw-r--r--engines/sci/sci.cpp10
9 files changed, 86 insertions, 40 deletions
diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp
index 42be711499..f905244011 100644
--- a/engines/sci/gfx/gfx_driver.cpp
+++ b/engines/sci/gfx/gfx_driver.cpp
@@ -26,18 +26,19 @@
#include "common/scummsys.h"
#include "common/system.h"
#include "graphics/primitives.h"
+#include "graphics/surface.h"
#include "sci/sci.h"
#include "sci/gfx/gfx_driver.h"
#include "sci/gfx/gfx_tools.h"
+
namespace Sci {
-GfxDriver::GfxDriver(int xfact, int yfact, int bytespp) {
+GfxDriver::GfxDriver(int xfact, int yfact, Graphics::PixelFormat format) {
int i;
- Graphics::PixelFormat format(bytespp, 0, 0, 0, 0, 0, 0, 0, 0);
- _mode = gfx_new_mode(xfact, yfact, format, new Palette(256), 0);
+ _mode = gfx_new_mode(xfact, yfact, format, format.bytesPerPixel == 1 ? new Palette(256) : 0, 0);
_mode->xsize = xfact * 320;
_mode->ysize = yfact * 200;
@@ -50,14 +51,15 @@ GfxDriver::GfxDriver(int xfact, int yfact, int bytespp) {
// create the visual buffers
for (i = 0; i < 2; i++) {
_visual[i] = NULL;
- _visual[i] = new byte[_mode->xsize * _mode->ysize];
+ _visual[i] = new byte[_mode->xsize * _mode->ysize * _mode->bytespp];
if (!_visual[i]) {
error("Out of memory: Could not allocate visual buffers! (%dx%d)\n", _mode->xsize, _mode->ysize);
}
- memset(_visual[i], 0, _mode->xsize * _mode->ysize);
+ memset(_visual[i], 0, _mode->xsize * _mode->ysize * _mode->bytespp);
}
- _mode->palette->name = "global";
+ if (_mode->palette)
+ _mode->palette->name = "global";
}
GfxDriver::~GfxDriver() {
@@ -76,10 +78,12 @@ GfxDriver::~GfxDriver() {
// Drawing operations
+template<int COPY_BYTES, typename SIZETYPE, int EXTRA_BYTE_OFFSET>
static void drawProc(int x, int y, int c, void *data) {
GfxDriver *drv = (GfxDriver *)data;
byte *p = drv->getVisual0();
- p[y * 320* drv->getMode()->xfact + x] = c;
+ SIZETYPE col = c << (EXTRA_BYTE_OFFSET * 8);
+ memcpy(p + (y * 320* drv->getMode()->xfact + x) * COPY_BYTES, &col, COPY_BYTES);
}
int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t color,
@@ -90,6 +94,28 @@ int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t colo
int xsize = _mode->xsize;
int ysize = _mode->ysize;
+ void (*modeDrawProc)(int,int,int,void*);
+ switch (_mode->bytespp) {
+ case 1:
+ modeDrawProc = drawProc<1, uint8, 0>;
+ break;
+ case 2:
+ modeDrawProc = drawProc<2, uint16, 0>;
+ break;
+ case 3:
+#ifdef SCUMM_BIG_ENDIAN
+ modeDrawProc = drawProc<3, uint32, 1>;
+#else
+ modeDrawProc = drawProc<3, uint32, 0>;
+#endif
+ break;
+ case 4:
+ modeDrawProc = drawProc<4, uint32, 0>;
+ break;
+ default:
+ GFXERROR("Invalid mode->bytespp=%d\n", _mode->bytespp);
+ }
+
if (color.mask & GFX_MASK_VISUAL) {
Common::Point nstart, nend;
@@ -101,7 +127,7 @@ int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t colo
nend.x = CLIP<int16>(end.x + xc, 0, xsize - 1);
nend.y = CLIP<int16>(end.y + yc, 0, ysize - 1);
- Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, drawProc, this);
+ Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, modeDrawProc, this);
if (color.mask & GFX_MASK_PRIORITY) {
gfx_draw_line_pixmap_i(_priority[0], nstart, nend, color.priority);
@@ -117,7 +143,8 @@ int GfxDriver::drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color
gfx_rectangle_fill_t shade_mode) {
if (color1.mask & GFX_MASK_VISUAL) {
for (int i = rect.y; i < rect.y + rect.height; i++) {
- memset(_visual[0] + i * _mode->xsize + rect.x, color1.visual.parent_index, rect.width);
+ memset(_visual[0] + (i * _mode->xsize + rect.x) * _mode->bytespp,
+ color1.visual.parent_index, rect.width * _mode->bytespp);
}
}
@@ -137,8 +164,10 @@ int GfxDriver::drawPixmap(gfx_pixmap_t *pxm, int priority, rect_t src, rect_t de
return GFX_ERROR;
}
- gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr], _mode->xsize,
- _priority[bufnr]->index_data, _priority[bufnr]->index_width, 1, 0);
+ gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr],
+ _mode->xsize * _mode->bytespp,
+ _priority[bufnr]->index_data,
+ _priority[bufnr]->index_width, 1, 0);
return GFX_OK;
}
@@ -160,7 +189,9 @@ int GfxDriver::grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map) {
pxm->width = src.width;
pxm->height = src.height;
for (int i = 0; i < src.height; i++) {
- memcpy(pxm->data + i * src.width, _visual[0] + (i + src.y) * _mode->xsize + src.x, src.width);
+ memcpy(pxm->data + i * src.width * _mode->bytespp,
+ _visual[0] + _mode->bytespp * ((i + src.y) * _mode->xsize + src.x),
+ src.width * _mode->bytespp);
}
break;
@@ -192,17 +223,18 @@ int GfxDriver::update(rect_t src, Common::Point dest, gfx_buffer_t buffer) {
switch (buffer) {
case GFX_BUFFER_BACK:
for (int i = 0; i < src.height; i++) {
- memcpy(_visual[0] + (dest.y + i) * _mode->xsize + dest.x,
- _visual[1] + (src.y + i) * _mode->xsize + src.x, src.width);
+ memcpy(_visual[0] + _mode->bytespp * ( (dest.y + i) * _mode->xsize + dest.x),
+ _visual[1] + _mode->bytespp * ( (src.y + i) * _mode->xsize + src.x), src.width * _mode->bytespp );
}
if ((src.x == dest.x) && (src.y == dest.y))
gfx_copy_pixmap_box_i(_priority[0], _priority[1], src);
break;
- case GFX_BUFFER_FRONT:
- g_system->copyRectToScreen(_visual[0] + src.x + src.y * _mode->xsize, _mode->xsize, dest.x, dest.y, src.width, src.height);
+ case GFX_BUFFER_FRONT: {
+ g_system->copyRectToScreen(_visual[0] + _mode->bytespp * (src.x + src.y * _mode->xsize), _mode->xsize * _mode->bytespp, dest.x, dest.y, src.width, src.height);
g_system->updateScreen();
break;
+ }
default:
GFXERROR("Invalid buffer %d in update!\n", buffer);
return GFX_ERROR;
@@ -212,7 +244,7 @@ int GfxDriver::update(rect_t src, Common::Point dest, gfx_buffer_t buffer) {
}
int GfxDriver::setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority) {
- memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize);
+ memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize * _mode->bytespp);
gfx_copy_pixmap_box_i(_priority[1], priority, gfx_rect(0, 0, _mode->xsize, _mode->ysize));
return GFX_OK;
diff --git a/engines/sci/gfx/gfx_driver.h b/engines/sci/gfx/gfx_driver.h
index b74511de77..4017dc3918 100644
--- a/engines/sci/gfx/gfx_driver.h
+++ b/engines/sci/gfx/gfx_driver.h
@@ -29,6 +29,8 @@
#include "sci/gfx/gfx_system.h"
#include "sci/uinput.h"
+#include "graphics/pixelformat.h"
+
namespace Sci {
enum gfx_buffer_t {
@@ -66,12 +68,11 @@ class GfxDriver {
public:
/*** Initialization ***/
- GfxDriver(int xfact, int yfact, int bytespp);
+ GfxDriver(int xfact, int yfact, Graphics::PixelFormat mode);
/* Attempts to initialize a specific graphics mode
** Parameters: (int x int) xres, yres: Horizontal and vertical scaling
** factors
- ** (int) bytespp: Any of GFX_COLOR_MODE_*. GFX_COLOR_MODE_INDEX
- ** implies color index mode.
+ ** (PixelFormat) mode: The mode to use
** Returns : (int) GFX_OK on success, GFX_ERROR if the mode could not be
** set, or GFX_FATAL if the graphics target is unuseable.
** The scaling factors apply to the standard SCI resolution of 320x200 pixels
diff --git a/engines/sci/gfx/gfx_pixmap_scale.cpp b/engines/sci/gfx/gfx_pixmap_scale.cpp
index 52c7b12396..37843743b9 100644
--- a/engines/sci/gfx/gfx_pixmap_scale.cpp
+++ b/engines/sci/gfx/gfx_pixmap_scale.cpp
@@ -70,14 +70,11 @@ void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale
// Calculate all colors
for (i = 0; i < pxm->colors_nr(); i++) {
int col;
-
const PaletteEntry& color = pxm->palette->getColor(i);
if (mode->palette)
col = color.parent_index;
else {
- col = mode->red_mask & ((EXTEND_COLOR(color.r)) >> mode->red_shift);
- col |= mode->green_mask & ((EXTEND_COLOR(color.g)) >> mode->green_shift);
- col |= mode->blue_mask & ((EXTEND_COLOR(color.b)) >> mode->blue_shift);
+ col = mode->format.ARGBToColor(0, color.r, color.g, color.b);
col |= alpha_ormask;
}
result_colors[i] = col;
diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp
index c5269bc544..229470a658 100644
--- a/engines/sci/gfx/gfx_resmgr.cpp
+++ b/engines/sci/gfx/gfx_resmgr.cpp
@@ -268,7 +268,8 @@ void GfxResManager::setStaticPalette(Palette *newPalette)
_staticPalette = newPalette;
_staticPalette->name = "static palette";
- _staticPalette->mergeInto(_driver->getMode()->palette);
+ if (_driver->getMode()->palette)
+ _staticPalette->mergeInto(_driver->getMode()->palette);
}
#if 0
diff --git a/engines/sci/gfx/gfx_system.h b/engines/sci/gfx/gfx_system.h
index bc25364b92..e1d56ee26d 100644
--- a/engines/sci/gfx/gfx_system.h
+++ b/engines/sci/gfx/gfx_system.h
@@ -30,6 +30,7 @@
#include "common/rect.h"
#include "sci/tools.h"
#include "sci/gfx/palette.h"
+#include "graphics/pixelformat.h"
namespace Sci {
@@ -70,8 +71,10 @@ struct gfx_mode_t {
// Palette mode is only supported for bytespp = 1
/* Color masks */
+ // TODO: remove those
uint32 red_mask, green_mask, blue_mask, alpha_mask;
short red_shift, green_shift, blue_shift, alpha_shift;
+ Graphics::PixelFormat format;
/* Each of the mask/shift pairs describe where the corresponding color
** values are stored for the described mode. Internally, color
diff --git a/engines/sci/gfx/gfx_tools.cpp b/engines/sci/gfx/gfx_tools.cpp
index e1378e14d0..4e570f5931 100644
--- a/engines/sci/gfx/gfx_tools.cpp
+++ b/engines/sci/gfx/gfx_tools.cpp
@@ -49,6 +49,7 @@ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &form
mode->xfact = xfact;
mode->yfact = yfact;
mode->bytespp = format.bytesPerPixel;
+ mode->format = format;
// FIXME: I am not sure whether the following assignments are quite right.
// The only code using these are the built-in scalers of the SCI engine.
@@ -60,10 +61,10 @@ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &form
mode->green_mask = format.ARGBToColor(0, 0, 0xFF, 0);
mode->blue_mask = format.ARGBToColor(0, 0, 0, 0xFF);
mode->alpha_mask = format.ARGBToColor(0xFF, 0, 0, 0);
- mode->red_shift = format.rLoss;
- mode->green_shift = format.gLoss;
- mode->blue_shift = format.bLoss;
- mode->alpha_shift = format.aLoss;
+ mode->red_shift = format.rShift;
+ mode->green_shift = format.gShift;
+ mode->blue_shift = format.bShift;
+ mode->alpha_shift = format.aShift;
} else {
mode->red_mask = mode->green_mask = mode->blue_mask = 0;
mode->alpha_mask = 0;
diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp
index cb73771528..56a8b8336b 100644
--- a/engines/sci/gfx/operations.cpp
+++ b/engines/sci/gfx/operations.cpp
@@ -411,9 +411,9 @@ static void init_aux_pixmap(gfx_pixmap_t **pixmap) {
(*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR);
}
-int gfxop_init(int version, bool isVGA, GfxState *state, gfx_options_t *options, ResourceManager *resManager,
- int xfact, int yfact, gfx_color_mode_t bpp) {
- int color_depth = bpp ? bpp : 1;
+int gfxop_init(int version, bool isVGA, GfxState *state,
+ gfx_options_t *options, ResourceManager *resManager,
+ Graphics::PixelFormat mode, int xfact, int yfact) {
int initialized = 0;
BASIC_CHECKS(GFX_FATAL);
@@ -430,7 +430,7 @@ int gfxop_init(int version, bool isVGA, GfxState *state, gfx_options_t *options,
state->pic_port_bounds = gfx_rect(0, 10, 320, 190);
state->_dirtyRects.clear();
- state->driver = new GfxDriver(xfact, yfact, bpp);
+ state->driver = new GfxDriver(xfact, yfact, mode);
state->gfxResMan = new GfxResManager(version, isVGA, state->options, state->driver, resManager);
@@ -1165,8 +1165,10 @@ static int _gfxop_set_pointer(GfxState *state, gfx_pixmap_t *pxm, Common::Point
// may change when a new PIC is loaded. The cursor has to be regenerated
// from this pxm at that point. (An alternative might be to ensure the
// cursor only uses colours in the static part of the palette?)
- if (pxm && pxm->palette)
+ if (pxm && state->driver->getMode()->palette) {
+ assert(pxm->palette);
pxm->palette->mergeInto(state->driver->getMode()->palette);
+ }
state->driver->setPointer(pxm, hotspot);
return GFX_OK;
@@ -1761,7 +1763,8 @@ static int _gfxop_set_pic(GfxState *state) {
// FIXME: The _gfxop_install_pixmap call below updates the OSystem palette.
// This is too soon, since it causes brief palette corruption until the
// screen is updated too. (Possibly related: EngineState::pic_not_valid .)
- state->pic->visual_map->palette->forceInto(state->driver->getMode()->palette);
+ if (state->driver->getMode()->palette)
+ state->pic->visual_map->palette->forceInto(state->driver->getMode()->palette);
_gfxop_install_pixmap(state->driver, state->pic->visual_map);
#ifdef CUSTOM_GRAPHICS_OPTIONS
diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h
index d559d3b6d2..ed71c32b65 100644
--- a/engines/sci/gfx/operations.h
+++ b/engines/sci/gfx/operations.h
@@ -136,14 +136,14 @@ struct GfxState {
/* Fundamental operations */
/**************************/
-int gfxop_init(int version, bool isVGA, GfxState *state, gfx_options_t *options, ResourceManager *resManager,
- int xfact = 1, int yfact = 1, gfx_color_mode_t bpp = GFX_COLOR_MODE_INDEX);
+int gfxop_init(int version, bool isVGA, GfxState *state,
+ gfx_options_t *options, ResourceManager *resManager,
+ Graphics::PixelFormat mode, int xfact = 1, int yfact = 1);
/* Initializes a graphics mode
** Parameters: (int) version: The interpreter version
** (GfxState *) state: The state to initialize
** (int x int) xfact, yfact: Horizontal and vertical scale factors
-** (gfx_color_mode_t) bpp: Bytes per pixel to initialize with, or
-** 0 (GFX_COLOR_MODE_AUTO) to auto-detect
+** (PixelFormat) mode: Graphics mode to use
** (gfx_options_t *) options: Rendering options
** (void *) misc_info: Additional information for the interpreter
** part of the resource loader
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index f58d729bf6..44ad13b93e 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -102,7 +102,15 @@ SciEngine::~SciEngine() {
}
Common::Error SciEngine::run() {
+ Graphics::PixelFormat gfxmode;
+#ifdef ENABLE_RGB_COLOR
+ gfxmode = _system->getSupportedFormats().front();
+ initGraphics(320, 200, false, gfxmode);
+ // TODO: check if this succeeded? (How?)
+#else
+ gfxmode = Graphics::PixelFormat::createFormatCLUT8();
initGraphics(320, 200, false);
+#endif
// Create debugger console. It requires GFX to be initialized
_console = new Console(this);
@@ -222,7 +230,7 @@ Common::Error SciEngine::run() {
#endif
bool isVGA = _resmgr->_sciVersion >= SCI_VERSION_01_VGA && !(getFlags() & GF_SCI1_EGA);
- if (gfxop_init(_resmgr->_sciVersion, isVGA, &gfx_state, &gfx_options, _resmgr)) {
+ if (gfxop_init(_resmgr->_sciVersion, isVGA, &gfx_state, &gfx_options, _resmgr, gfxmode, 1, 1)) {
warning("Graphics initialization failed. Aborting...");
return Common::kUnknownError;
}