diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 1dfd70b4038..d6abe4c40ac 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -1197,7 +1197,7 @@ bool Console::cmdVisualState(int argc, const char **argv) { } bool Console::cmdFlushPorts(int argc, const char **argv) { - _vm->_gamestate->_cursor->setShape(GFXOP_NO_POINTER); + _vm->_gamestate->_gui->hideCursor(); DebugPrintf("Flushing dynamically allocated ports (for memory profiling)...\n"); delete _vm->_gamestate->visual; _vm->_gamestate->gfx_state->gfxResMan->freeAllResources(); diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 741acaeca30..970ac2786b1 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -516,7 +516,7 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) { hotspot = new Common::Point(argv[3].toSint16(), argv[4].toSint16()); // Fallthrough case 3: - gfxop_set_pointer_view(s->gfx_state, argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), hotspot); + s->_gui->setCursorView(argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), hotspot); if (hotspot) delete hotspot; break; diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp index 78ed7620e97..8ac2e8e1d90 100644 --- a/engines/sci/gfx/gfx_driver.cpp +++ b/engines/sci/gfx/gfx_driver.cpp @@ -183,45 +183,6 @@ void GfxDriver::setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority) { memcpy(_screen->_controlScreen, priority->index_data, _mode->xsize * _mode->ysize); } -// Mouse pointer operations - -void GfxDriver::setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot) { - if (!pointer || !hotspot) { - CursorMan.showMouse(false); - return; - } - - pointer->palette->mergeInto(_mode->palette); - - // Scale cursor and map its colors to the global palette - byte *cursorData = new byte[pointer->width * pointer->height]; - - for (int yc = 0; yc < pointer->index_height; yc++) { - byte *linebase = &cursorData[yc * (pointer->width * _mode->scaleFactor)]; - - for (int xc = 0; xc < pointer->index_width; xc++) { - byte color = pointer->index_data[yc * pointer->index_width + xc]; - if (color < pointer->palette->size()) - color = pointer->palette->getColor(color).getParentIndex(); - memset(&linebase[xc], color, _mode->scaleFactor); - } - - // Scale vertically - for (int scalectr = 1; scalectr < _mode->scaleFactor; scalectr++) - memcpy(&linebase[pointer->width * scalectr], linebase, pointer->width); - } - - byte color_key = pointer->color_key; - if ((pointer->color_key != GFX_PIXMAP_COLOR_KEY_NONE) && ((uint)pointer->color_key < pointer->palette->size())) - color_key = pointer->palette->getColor(pointer->color_key).getParentIndex(); - - CursorMan.replaceCursor(cursorData, pointer->width, pointer->height, hotspot->x, hotspot->y, color_key); - CursorMan.showMouse(true); - - delete[] cursorData; - cursorData = 0; -} - void GfxDriver::animatePalette(int fromColor, int toColor, int stepCount) { int i; PaletteEntry firstColor = _mode->palette->getColor(fromColor); diff --git a/engines/sci/gfx/gfx_driver.h b/engines/sci/gfx/gfx_driver.h index 8983111b5ba..5fb6b35ef34 100644 --- a/engines/sci/gfx/gfx_driver.h +++ b/engines/sci/gfx/gfx_driver.h @@ -206,25 +206,6 @@ public: void setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority); /** @} */ - /** @name Mouse pointer operations */ - /** @{ */ - - /** - * Sets a new mouse pointer. - * - * If pointer is not NULL, it will have been scaled to the appropriate - * size and registered as a pixmap (if neccessary) beforehand. If this - * function is called for a target that supports only two-color - * pointers, the image is a color index image, where only color index - * values 0, 1, and GFX_COLOR_INDEX_TRANSPARENT are used. - * - * @param[in] pointer The pointer to set, or NULL to set no pointer. - * @param[in] hotspot The coordinates of the hotspot, or NULL to set - * no pointer. - */ - void setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot); - /** @} */ - gfx_mode_t *getMode() { return _mode; } /** diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp index a07188bca68..06549050a7a 100644 --- a/engines/sci/gfx/operations.cpp +++ b/engines/sci/gfx/operations.cpp @@ -967,25 +967,6 @@ void gfxop_sleep(GfxState *state, uint32 msecs) { } } -void gfxop_set_pointer_view(GfxState *state, int nr, int loop, int cel, Common::Point *hotspot) { - // FIXME: For now, don't palettize pointers - gfx_pixmap_t *new_pointer = state->gfxResMan->getView(nr, &loop, &cel, 0)->loops[loop].cels[cel]; - - // Eco Quest 1 uses a 1x1 transparent cursor to hide the cursor from the user. Some scalers don't seem to support this. - if (new_pointer->width < 2 || new_pointer->height < 2) { - state->driver->setPointer(NULL, NULL); - return; - } - - if (hotspot) - state->driver->setPointer(new_pointer, hotspot); - else { - // Compute hotspot from xoffset/yoffset - Common::Point p = Common::Point(new_pointer->xoffset + (new_pointer->width >> 1), new_pointer->yoffset + new_pointer->height - 1); - state->driver->setPointer(new_pointer, &p); - } -} - #define SCANCODE_ROWS_NR 3 struct scancode_row { diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h index ea2078f49a5..e620fc98337 100644 --- a/engines/sci/gfx/operations.h +++ b/engines/sci/gfx/operations.h @@ -40,8 +40,6 @@ namespace Sci { struct TextFragment; -#define GFXOP_NO_POINTER -1 - /* Threshold in color index mode to differentiate between visible and non-visible stuff. ** GFXOP_ALPHA_THRESHOLD itself should be treated as non-visible. */ @@ -363,19 +361,6 @@ void gfxop_free_color(GfxState *state, gfx_color_t *color); */ void gfxop_sleep(GfxState *state, uint32 msecs); -/** - * Sets the mouse pointer to a view resource. - * - * Use gfxop_set_pointer_cursor(state, GFXOP_NO_POINTER) to disable the pointer. - * - * @param[in] state The affected state - * @param[in] nr Number of the view resource to use - * @param[in] loop View loop to use - * @param[in] cel View cel to use - * @param[in] hotspot Manually set hotspot to use, or NULL for default. - */ -void gfxop_set_pointer_view(GfxState *state, int nr, int loop, int cel, Common::Point *hotspot); - /** * Retrieves the next input event from the driver. * diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp index ce26d75974e..65d6088db19 100644 --- a/engines/sci/gui/gui.cpp +++ b/engines/sci/gui/gui.cpp @@ -601,6 +601,10 @@ void SciGui::setCursorShape(GuiResourceId cursorId) { _cursor->setShape(cursorId); } +void SciGui::setCursorView(GuiResourceId viewNum, int loopNum, int cellNum, Common::Point *hotspot) { + _cursor->setView(viewNum, loopNum, cellNum, hotspot); +} + void SciGui::setCursorPos(Common::Point pos) { pos.y += _gfx->GetPort()->top; pos.x += _gfx->GetPort()->left; diff --git a/engines/sci/gui/gui.h b/engines/sci/gui/gui.h index f81bd00675e..0d8e75f2141 100644 --- a/engines/sci/gui/gui.h +++ b/engines/sci/gui/gui.h @@ -105,6 +105,7 @@ public: virtual void hideCursor(); virtual void showCursor(); virtual void setCursorShape(GuiResourceId cursorId); + virtual void setCursorView(GuiResourceId viewNum, int loopNum, int cellNum, Common::Point *hotspot); virtual void setCursorPos(Common::Point pos); virtual void moveCursor(Common::Point pos); diff --git a/engines/sci/gui/gui_cursor.cpp b/engines/sci/gui/gui_cursor.cpp index 68e376f66d6..ba55fe75e2f 100644 --- a/engines/sci/gui/gui_cursor.cpp +++ b/engines/sci/gui/gui_cursor.cpp @@ -38,7 +38,6 @@ namespace Sci { SciGuiCursor::SciGuiCursor(ResourceManager *resMan, SciGuiPalette *palette) : _resMan(resMan), _palette(palette) { - _rawBitmap = NULL; setPosition(Common::Point(160, 150)); // TODO: how is that different in 640x400 games? setMoveZone(Common::Rect(0, 0, 320, 200)); // TODO: hires games @@ -64,10 +63,12 @@ void SciGuiCursor::setShape(GuiResourceId resourceId) { byte color; int16 maskA, maskB; byte *pOut; + byte *rawBitmap = new byte[SCI_CURSOR_SCI0_HEIGHTWIDTH * SCI_CURSOR_SCI0_HEIGHTWIDTH]; if (resourceId == -1) { // no resourceId given, so we actually hide the cursor hide(); + delete rawBitmap; return; } @@ -95,10 +96,7 @@ void SciGuiCursor::setShape(GuiResourceId resourceId) { // Seek to actual data resourceData += 4; - if (!_rawBitmap) - _rawBitmap = new byte[SCI_CURSOR_SCI0_HEIGHTWIDTH*SCI_CURSOR_SCI0_HEIGHTWIDTH]; - - pOut = _rawBitmap; + pOut = rawBitmap; for (y = 0; y < SCI_CURSOR_SCI0_HEIGHTWIDTH; y++) { maskA = READ_LE_UINT16(resourceData + (y << 1)); maskB = READ_LE_UINT16(resourceData + 32 + (y << 1)); @@ -109,8 +107,39 @@ void SciGuiCursor::setShape(GuiResourceId resourceId) { } } - CursorMan.replaceCursor(_rawBitmap, SCI_CURSOR_SCI0_HEIGHTWIDTH, SCI_CURSOR_SCI0_HEIGHTWIDTH, hotspot.x, hotspot.y, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR); + CursorMan.replaceCursor(rawBitmap, SCI_CURSOR_SCI0_HEIGHTWIDTH, SCI_CURSOR_SCI0_HEIGHTWIDTH, hotspot.x, hotspot.y, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR); CursorMan.showMouse(true); + + delete rawBitmap; +} + +void SciGuiCursor::setView(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot) { + SciGuiView *cursorView = new SciGuiView(_resMan, _screen, _palette, viewNum); + + sciViewCelInfo *celInfo = cursorView->getCelInfo(loopNum, celNum); + int16 width = celInfo->width; + int16 height = celInfo->height; + byte clearKey = celInfo->clearKey; + Common::Point *cursorHotspot = hotspot; + if (!cursorHotspot) + // Compute hotspot from xoffset/yoffset + cursorHotspot = new Common::Point((celInfo->width >> 1) - celInfo->displaceX, celInfo->height - celInfo->displaceY - 1); + + // Eco Quest 1 uses a 1x1 transparent cursor to hide the cursor from the user. Some scalers don't seem to support this + if (width < 2 || height < 2) { + hide(); + delete cursorHotspot; + delete cursorView; + return; + } + + cursorView->getBitmap(loopNum, celNum); + + CursorMan.replaceCursor(celInfo->rawBitmap, width, height, cursorHotspot->x, cursorHotspot->y, clearKey); + show(); + + delete cursorHotspot; + delete cursorView; } void SciGuiCursor::setPosition(Common::Point pos) { diff --git a/engines/sci/gui/gui_cursor.h b/engines/sci/gui/gui_cursor.h index 6a52dac4985..9e237720caf 100644 --- a/engines/sci/gui/gui_cursor.h +++ b/engines/sci/gui/gui_cursor.h @@ -43,6 +43,7 @@ public: void show(); void hide(); void setShape(GuiResourceId resourceId); + void setView(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot); void setPosition(Common::Point pos); Common::Point getPosition(); void refreshPosition(); @@ -59,7 +60,6 @@ private: SciGuiScreen *_screen; SciGuiPalette *_palette; - byte *_rawBitmap; Common::Rect _moveZone; // Rectangle in which the pointer can move }; diff --git a/engines/sci/gui32/gui32.cpp b/engines/sci/gui32/gui32.cpp index f147c89dffa..83c12d5c379 100644 --- a/engines/sci/gui32/gui32.cpp +++ b/engines/sci/gui32/gui32.cpp @@ -2457,6 +2457,10 @@ void SciGui32::setCursorShape(GuiResourceId cursorId) { _cursor->setShape(cursorId); } +void SciGui32::setCursorView(GuiResourceId viewNum, int loopNum, int cellNum, Common::Point *hotspot) { + _cursor->setView(viewNum, loopNum, cellNum, hotspot); +} + void SciGui32::setCursorPos(Common::Point pos) { pos.y += s->port->_bounds.y; pos.x += s->port->_bounds.x; diff --git a/engines/sci/gui32/gui32.h b/engines/sci/gui32/gui32.h index 76bb81d1f9a..34a33aff57d 100644 --- a/engines/sci/gui32/gui32.h +++ b/engines/sci/gui32/gui32.h @@ -95,6 +95,7 @@ public: void hideCursor(); void showCursor(); void setCursorShape(GuiResourceId cursorId); + void setCursorView(GuiResourceId viewNum, int loopNum, int cellNum, Common::Point *hotspot); void setCursorPos(Common::Point pos); void moveCursor(Common::Point pos);