diff options
-rw-r--r-- | engines/sci/gfx/gfx_driver.cpp | 66 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_driver.h | 7 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_pixmap_scale.cpp | 5 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.cpp | 3 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_system.h | 3 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_tools.cpp | 9 | ||||
-rw-r--r-- | engines/sci/gfx/operations.cpp | 15 | ||||
-rw-r--r-- | engines/sci/gfx/operations.h | 8 | ||||
-rw-r--r-- | engines/sci/sci.cpp | 10 |
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; } |