diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/gfx/gfx_driver.cpp | 66 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_driver.h | 4 | ||||
-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 | 16 | ||||
-rw-r--r-- | engines/sci/gfx/operations.h | 9 | ||||
-rw-r--r-- | engines/sci/gfx/res_pic.cpp | 4 | ||||
-rw-r--r-- | engines/sci/sci.cpp | 8 |
10 files changed, 86 insertions, 41 deletions
diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp index 0b1387074c..b71152822c 100644 --- a/engines/sci/gfx/gfx_driver.cpp +++ b/engines/sci/gfx/gfx_driver.cpp @@ -27,18 +27,19 @@ #include "common/system.h" #include "graphics/cursorman.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; @@ -51,14 +52,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() { @@ -77,10 +79,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, @@ -91,6 +95,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: + error("Invalid mode->bytespp=%d", _mode->bytespp); + } + if (color.mask & GFX_MASK_VISUAL) { Common::Point nstart, nend; @@ -102,7 +128,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); @@ -118,7 +144,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); } } @@ -138,8 +165,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; } @@ -161,7 +190,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; @@ -193,17 +224,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: error("Invalid buffer %d in update", buffer); return GFX_ERROR; @@ -213,7 +245,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 f7cbd0b6c2..cc8a5208d4 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 { @@ -85,7 +87,7 @@ public: * not be set, or GFX_FATAL if the graphics target * is unuseable. */ - GfxDriver(int xfact, int yfact, int bytespp); + GfxDriver(int xfact, int yfact, Graphics::PixelFormat mode); /** * Uninitializes the current graphics mode. diff --git a/engines/sci/gfx/gfx_pixmap_scale.cpp b/engines/sci/gfx/gfx_pixmap_scale.cpp index 034efafe8d..41e6102cbd 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 4a3c79feef..b8c005b620 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -274,7 +274,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 855f9b196e..fe93922e21 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 { @@ -74,8 +75,10 @@ struct gfx_mode_t { */ Palette *palette; + // TODO: remove those uint32 red_mask, green_mask, blue_mask, alpha_mask; short red_shift, green_shift, blue_shift, alpha_shift; + Graphics::PixelFormat format; }; diff --git a/engines/sci/gfx/gfx_tools.cpp b/engines/sci/gfx/gfx_tools.cpp index e3d35ecb14..9e81ec1a8a 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 2c536912b3..77b887778b 100644 --- a/engines/sci/gfx/operations.cpp +++ b/engines/sci/gfx/operations.cpp @@ -404,8 +404,9 @@ static void init_aux_pixmap(gfx_pixmap_t **pixmap) { (*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR); } -int gfxop_init(int version, GfxState *state, gfx_options_t *options, ResourceManager *resManager, - int xfact, int yfact, gfx_color_mode_t bpp) { +int gfxop_init(int version, GfxState *state, + gfx_options_t *options, ResourceManager *resManager, + Graphics::PixelFormat mode, int xfact, int yfact) { //int color_depth = bpp ? bpp : 1; //int initialized = 0; @@ -421,7 +422,7 @@ int gfxop_init(int version, GfxState *state, gfx_options_t *options, ResourceMan 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(state->options, state->driver, resManager); @@ -1131,8 +1132,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; @@ -1712,7 +1715,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 @@ -1735,7 +1739,7 @@ int gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette) { if (state->driver->getMode()->xfact == 1 && state->driver->getMode()->yfact == 1) { state->pic_unscaled = state->pic; } else { - state->pic = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false); + state->pic_unscaled = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false); } if (!state->pic || !state->pic_unscaled) { diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h index b9a16d4a27..ec0a810224 100644 --- a/engines/sci/gfx/operations.h +++ b/engines/sci/gfx/operations.h @@ -138,17 +138,16 @@ struct GfxState { * @param[in] state The state to initialize * @param[in] xfact Horizontal scale factor * @param[in] yfact Vertical scale factors - * @param[in] bpp Bytes per pixel to initialize with, or 0 - * (GFX_COLOR_MODE_AUTO) to auto-detect + * @param[in] mode Graphics mode to use * @param[in] options Rendering options * @param[in] resManager Resource manager to use * @return GFX_OK on success, GFX_ERROR if that particular mode * is unavailable, or GFX_FATAL if the graphics driver * is unable to provide any useful graphics support */ -int gfxop_init(int version, 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, GfxState *state, + gfx_options_t *options, ResourceManager *resManager, + Graphics::PixelFormat mode, int xfact = 1, int yfact = 1); /** * Deinitializes a currently active driver. diff --git a/engines/sci/gfx/res_pic.cpp b/engines/sci/gfx/res_pic.cpp index e7b34976b0..6c35ad314e 100644 --- a/engines/sci/gfx/res_pic.cpp +++ b/engines/sci/gfx/res_pic.cpp @@ -1548,7 +1548,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, view->index_height = CLIP<int>(view->index_height, 0, portBounds.height()); // Set up mode structure for resizing the view - Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1byte/p, which handles masks and the rest for us + Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1byte/p, which handles masks and the rest for us gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, pic->visual_map->index_height / 200, format, view->palette, 0); @@ -1654,7 +1654,7 @@ void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, view->palette = pic->visual_map->palette->getref(); // Set up mode structure for resizing the view - Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1 byte/p, which handles masks and the rest for us + Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1 byte/p, which handles masks and the rest for us gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, pic->visual_map->index_height / 200, format, view->palette, 0); gfx_xlate_pixmap(view, mode, GFX_XLATE_FILTER_NONE); diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 504e38c7c1..af8aac3147 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -107,7 +107,13 @@ SciEngine::~SciEngine() { } Common::Error SciEngine::run() { + Graphics::PixelFormat gfxmode; +#ifdef ENABLE_RGB_COLOR + initGraphics(320, 200, false, NULL); +#else initGraphics(320, 200, false); +#endif + gfxmode = _system->getScreenFormat(); // Create debugger console. It requires GFX to be initialized _console = new Console(this); @@ -209,7 +215,7 @@ Common::Error SciEngine::run() { // Default config ends #endif - if (gfxop_init(_resmgr->_sciVersion, &gfx_state, &gfx_options, _resmgr)) { + if (gfxop_init(_resmgr->_sciVersion, &gfx_state, &gfx_options, _resmgr, gfxmode, 1, 1)) { warning("Graphics initialization failed. Aborting..."); return Common::kUnknownError; } |