diff options
author | Filippos Karapetis | 2010-01-05 00:54:53 +0000 |
---|---|---|
committer | Filippos Karapetis | 2010-01-05 00:54:53 +0000 |
commit | f66d5a7f534ad2869aecfcacc90bf337cc33571e (patch) | |
tree | 9a163a79eca70af6f7cf9cbe0f6f53fac692f93b /engines/sci/gfx | |
parent | 86cad51d0798ddad02fadc2380f39a8db2aa30fa (diff) | |
download | scummvm-rg350-f66d5a7f534ad2869aecfcacc90bf337cc33571e.tar.gz scummvm-rg350-f66d5a7f534ad2869aecfcacc90bf337cc33571e.tar.bz2 scummvm-rg350-f66d5a7f534ad2869aecfcacc90bf337cc33571e.zip |
SCI: Removed the old graphics code
svn-id: r47005
Diffstat (limited to 'engines/sci/gfx')
-rw-r--r-- | engines/sci/gfx/gfx_driver.cpp | 205 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_driver.h | 228 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_gui.cpp | 666 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_gui.h | 225 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_pixmap_scale.cpp | 133 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.cpp | 532 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.h | 289 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resource.cpp | 78 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resource.h | 289 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_state_internal.h | 417 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_support.cpp | 281 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_system.h | 286 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_tools.cpp | 163 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_tools.h | 191 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_widgets.cpp | 1775 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_widgets.h | 477 | ||||
-rw-r--r-- | engines/sci/gfx/menubar.cpp | 441 | ||||
-rw-r--r-- | engines/sci/gfx/menubar.h | 232 | ||||
-rw-r--r-- | engines/sci/gfx/operations.cpp | 1212 | ||||
-rw-r--r-- | engines/sci/gfx/operations.h | 530 | ||||
-rw-r--r-- | engines/sci/gfx/palette.cpp | 330 | ||||
-rw-r--r-- | engines/sci/gfx/palette.h | 129 |
22 files changed, 0 insertions, 9109 deletions
diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp deleted file mode 100644 index 41205a0ecc..0000000000 --- a/engines/sci/gfx/gfx_driver.cpp +++ /dev/null @@ -1,205 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "common/scummsys.h" -#include "common/system.h" -#include "graphics/cursorman.h" -#include "graphics/primitives.h" -#include "graphics/surface.h" - -#include "sci/gui/gui_screen.h" -#include "sci/gfx/gfx_driver.h" -#include "sci/gfx/gfx_tools.h" - -#include "sci/gui/gui_screen.h" - -namespace Sci { - - -GfxDriver::GfxDriver(SciGuiScreen *screen, int scaleFactor) : _screen(screen) { - _mode = gfx_new_mode(scaleFactor, new Palette(256)); - - if (_mode->palette) - _mode->palette->name = "global"; -} - -GfxDriver::~GfxDriver() { -} - - -// Drawing operations - -static void drawProc(int x, int y, int c, void *data) { - GfxDriver *drv = (GfxDriver *)data; - byte *p = drv->_screen->_displayScreen; - uint8 col = c; - memcpy(p + (y * drv->_screen->_width * drv->getMode()->scaleFactor + x), &col, 1); -} - -void GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) { - uint32 scolor = color.visual.getParentIndex(); - int scaleFactor = (line_mode == GFX_LINE_MODE_FINE)? 1: _mode->scaleFactor; - int xsize = _mode->xsize; - int ysize = _mode->ysize; - - if (color.mask & GFX_MASK_VISUAL) { - Common::Point nstart, nend; - - for (int xc = 0; xc < scaleFactor; xc++) { - for (int yc = 0; yc < scaleFactor; yc++) { - - nstart.x = CLIP<int16>(start.x + xc, 0, xsize); - nstart.y = CLIP<int16>(start.y + yc, 0, ysize); - 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); - - if (color.mask & GFX_MASK_PRIORITY) { - gfx_draw_line_buffer(_screen->_priorityScreen, 1, 1, nstart, nend, color.priority); - } - } - } - } -} - -void GfxDriver::drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) { - if (color1.mask & GFX_MASK_VISUAL) { - for (int i = rect.y; i < rect.y + rect.height; i++) { - memset(_screen->_displayScreen + (i * _mode->xsize + rect.x), - color1.visual.getParentIndex(), rect.width); - } - } - - if (color1.mask & GFX_MASK_PRIORITY) { - gfx_clip_box_basic(&rect, _screen->_width - 1, _screen->_height - 1); - gfx_draw_box_buffer(_screen->_priorityScreen, _screen->_width, rect, color1.priority); - } -} - -// Pixmap operations - -void GfxDriver::drawPixmap(gfx_pixmap_t *pxm, int priority, rect_t src, rect_t dest, gfx_buffer_t buffer) { - byte *destBuffer = (buffer == GFX_BUFFER_STATIC) ? _screen->_visualScreen : _screen->_displayScreen; - byte *destPriority = (buffer == GFX_BUFFER_STATIC) ? _screen->_controlScreen : _screen->_priorityScreen; - if (dest.width != src.width || dest.height != src.height) { - warning("Attempt to scale pixmap (%dx%d)->(%dx%d): Not supported\n", src.width, src.height, dest.width, dest.height); - return; - } - - gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, destBuffer, - _mode->xsize, - destPriority, - _screen->_width, 1); -} - -void GfxDriver::grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map) { - if (src.x < 0 || src.y < 0) - error("Attempt to grab pixmap from invalid coordinates (%d,%d)", src.x, src.y); - - if (!pxm->data) - error("Attempt to grab pixmap to unallocated memory"); - - switch (map) { - - case GFX_MASK_VISUAL: - pxm->width = src.width; - pxm->height = src.height; - for (int i = 0; i < src.height; i++) { - memcpy(pxm->data + i * src.width, - _screen->_displayScreen + ((i + src.y) * _mode->xsize + src.x), - src.width); - } - break; - - case GFX_MASK_PRIORITY: - warning("FIXME: priority map grab not implemented yet"); - break; - - default: - error("Attempt to grab pixmap from invalid map 0x%02x", map); - } -} - -// Buffer operations - -void 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(_screen->_displayScreen + ( (dest.y + i) * _mode->xsize + dest.x), - _screen->_visualScreen + ( (src.y + i) * _mode->xsize + src.x), src.width ); - } - - if ((src.x == dest.x) && (src.y == dest.y)) { - int offset = src.x + (src.y * _screen->_width); - - gfx_clip_box_basic(&src, _screen->_width, _screen->_height); - - while (src.height--) { - memcpy(_screen->_priorityScreen + offset, _screen->_controlScreen + offset, _screen->_width); - offset += _screen->_width; - } - } - break; - case GFX_BUFFER_FRONT: { - // TODO: we need to call SciGuiCursor::refreshPosition() before each screen update to limit the mouse cursor position - g_system->copyRectToScreen(_screen->_displayScreen + (src.x + src.y * _mode->xsize), _mode->xsize, dest.x, dest.y, src.width, src.height); - g_system->updateScreen(); - break; - } - default: - error("Invalid buffer %d in update", buffer); - } -} - -void GfxDriver::setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority) { - memcpy(_screen->_visualScreen, pic->data, _mode->xsize * _mode->ysize); - memcpy(_screen->_controlScreen, priority->index_data, _mode->xsize * _mode->ysize); -} - -void GfxDriver::animatePalette(int fromColor, int toColor, int stepCount) { - int i; - PaletteEntry firstColor = _mode->palette->getColor(fromColor); - PaletteEntry loopColor; - for (i = fromColor + 1; i <= toColor; i++) { - loopColor = _mode->palette->getColor(i); - loopColor.r = 0; - loopColor.g = 0; - loopColor.b = 0; - _mode->palette->makeSystemColor(i-1, loopColor); // loopColor.r, loopColor.g, loopColor.b); - } -// _mode->palette->setColor(toColor, firstColor.r, firstColor.g, firstColor.b); - _mode->palette->makeSystemColor(toColor, firstColor); -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_driver.h b/engines/sci/gfx/gfx_driver.h deleted file mode 100644 index e4f8bfd2f6..0000000000 --- a/engines/sci/gfx/gfx_driver.h +++ /dev/null @@ -1,228 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_DRIVER_H -#define SCI_GFX_GFX_DRIVER_H - -#include "sci/gfx/gfx_system.h" - -namespace Sci { - -enum gfx_buffer_t { - GFX_BUFFER_FRONT = 0, - GFX_BUFFER_BACK = 1, - GFX_BUFFER_STATIC = 2 -}; - -class SciGuiScreen; - - -/** - * Graphics driver. - * - * Principial graphics driver architecture: - * - * All graphics drivers must provide - * - One visual front buffer (the actually visible thing) - * - Two dynamic back buffers: - * - visual - * - priority - * - Two static buffers (containing the background image and picviews): - * - visual - * - priority - * - * The control buffer is handled outside the graphics driver architecture. - * Graphics are drawn by first setting the static buffers, then updating - * the back buffers (from the static buffers), adding all picviews and other - * widgets, and finally updating the front buffer. - * - * All coordinates refer to the scaled coordinate system. - * Invalid parameters should produce an error message. - * Support for some valid parameter values is optional (like different line - * modes). If an unsupported but valid parameter is specified, the function - * must use a reasonable default value. - */ -class GfxDriver { -public: - /** @name Initialization */ - /** @{ */ - /** - * Attempts to initialize a specific graphics mode. - * - * The scaling factors apply to the standard SCI resolution of 320x200 - * pixels and is used for internal representation of graphical data. - * The physical resolution set by the graphics driver may be different - * for practical reasons. - * Must also set _mode, preferably with the gfx_new_mode() function - * specified in gfx_tools.h. - * - * @param[in] xfact Horizontal scaling factor - * @param[in] yfact Vertical scaling factor - * @return GFX_OK on success, GFX_ERROR if the mode could - * not be set, or GFX_FATAL if the graphics target - * is unuseable. - */ - GfxDriver(SciGuiScreen *screen, int scaleFactor); - - /** - * Uninitializes the current graphics mode. - * - * This function frees all memory allocated by the graphics driver, - * including mode and palette information, uninstalls all console - * commands introduced by preceeding init() or init_specific() - * commands, and does any clean-up work (like closing visuals or - * returning to text mode) required by the graphics infrastructure used. - */ - ~GfxDriver(); - /** @} */ - - /** @name Drawing operations */ - /** @{ */ - - /** - * Draws a single line to the back buffer. - * - * Note that color.priority is relevant and must be drawn if - * (color.mask & GFX_MASK_PRIORITY). Support for line modes other than - * GFX_LINE_MODE_FAST is optional. For non-fine lines, the coordinates - * provided describe the upper left corner of the pixels of the line - * to draw.line_style support is optional, if - * GFX_CAPABILITY_STIPPLED_LINES is not set. - * - * @param[in] start Starting point of the line to draw - * @param[in] end End point of the line to draw - * @param[in] color The color to draw with - * @param[in] line_mode Any of the line modes - * @param[in] line_style Any of the line styles - */ - void drawLine(Common::Point start, Common::Point end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style); - - /** - * Draws a single filled and possibly shaded rectangle to the back - * buffer. - * - * Note that color.priority is relevant and must be drawn if - * (color.mask & GFX_MASK_PRIORITY). color2 is relevant only if - * shade_mode is not GFX_SHADE_FLAT. Support for shade modes other - * than GFX_SHADE_FLAT is optional. - * - * @param[in] rect The rectangle to draw - * @param[in] color1 The first color to draw with - * @param[in] color2 The second color to draw with - * @param[in] shade_mode Any of GFX_SHADE_*. - */ - void drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode); - /** @} */ - - /** @name Pixmap operations */ - /** @{ */ - - /** - * Draws part of a pixmap to the static or back buffer. - * - * @param[in] pxm The pixmap to draw - * @param[in] priority The priority to draw with, or GFX_NO_PRIORITY - * to draw on top of everything without setting the - * priority back buffer. - * @param[in] src The pixmap-relative source rectangle - * @param[in] dest The destination rectangle - * @param[in] buffer One of GFX_BUFFER_STATIC and GFX_BUFFER_BACK - */ - void drawPixmap(gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer); - - /** - * Grabs an image from the visual or priority back buffer. - * - * This function is now mandatory. - * - * @param[in] src The rectangle to grab - * @param[in] pxm The pixmap structure the data is to be written to - * @param[in] map GFX_MASK_VISUAL or GFX_MASK_PRIORITY - */ - void grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map); - /** @} */ - - /** @name Buffer operations */ - /** @{ */ - - /** - * Updates the front buffer or the back buffers. - * - * This function updates either the visual front buffer, or the two - * back buffers, by copying the specified source region to the - * destination region. - * For heuristical reasons, it may be assumed that the x and y fields - * of src and dest will be identical in /most/ cases.If they aren't, - * the priority map will not be required to be copied. - * - * @param[in] src: Source rectangle - * @param[in] dest: Destination point - * @param[in] buffer: One of GFX_BUFFER_FRONT or GFX_BUFFER_BACK - */ - void update(rect_t src, Common::Point dest, gfx_buffer_t buffer); - - /** - * Sets the contents of the static visual and priority buffers. - * - * pic and priority may be modified or written to freely. They may also - * be used as the actual static buffers, since they are not freed and - * reallocated between calls to set_static_buffer() and update(), - * unless exit() was called in between. - * Note that later version of the driver interface may disallow - * modifying pic and priority. pic and priority are always scaled to - * the appropriate resolution - * - * @param[in] pic The image defining the new content of the - * visual back buffer - * @param[in] priority The priority map containing the new content of - * the priority back buffer in the index buffer - */ - void setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority); - /** @} */ - - gfx_mode_t *getMode() { return _mode; } - - /** - * Animates palette - */ - void animatePalette(int fromColor, int toColor, int stepCount); - -public: // temporary hack - SciGuiScreen *_screen; -private: - gfx_mode_t *_mode; /**< Currently active mode, NULL if no mode is active */ -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_DRIVER_H - -#endif diff --git a/engines/sci/gfx/gfx_gui.cpp b/engines/sci/gfx/gfx_gui.cpp deleted file mode 100644 index 2cfe0f3a39..0000000000 --- a/engines/sci/gfx/gfx_gui.cpp +++ /dev/null @@ -1,666 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/engine/state.h" -#include "sci/gfx/operations.h" -#include "sci/gfx/gfx_widgets.h" -#include "sci/gfx/menubar.h" -#include "sci/gfx/gfx_gui.h" -#include "sci/gfx/gfx_state_internal.h" -#include "sci/gui32/font.h" -#include "sci/gui/gui_animate.h" - -#include "common/system.h" - -namespace Sci { - -#define SCI_SPECIAL_CHAR_ARROW_UP 0x18 -#define SCI_SPECIAL_CHAR_ARROW_DOWN 0x19 - -static void clear_titlebar(GfxPort *titlebar) { - if (titlebar->_contents) { - delete titlebar->_contents; - titlebar->_contents = NULL; - titlebar->_nextpp = &(titlebar->_contents); - } -} - -static GfxList *make_titlebar_list(EngineState *s, rect_t bounds, GfxPort *status_bar) { - gfx_color_t color = status_bar->_bgcolor; - GfxList *list; - GfxBox *bgbox; - - - list = gfxw_new_list(status_bar->_bounds, 0); - bgbox = gfxw_new_box(s->gfx_state, gfx_rect(0, 0, status_bar->_bounds.width, status_bar->_bounds.height - 1), - color, color, GFX_BOX_SHADE_FLAT); - - list->add((GfxContainer *) list, (GfxWidget *) bgbox); - - return list; -} - -static GfxList *finish_titlebar_list(EngineState *s, GfxList *list, GfxPort *status_bar) { - gfx_color_t black = s->ega_colors[0]; - GfxPrimitive *line; - - line = gfxw_new_line(Common::Point(0, status_bar->_bounds.height - 1), Common::Point(status_bar->_bounds.width, status_bar->_bounds.height - 1), - black, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL); - list->add((GfxContainer *)list, (GfxWidget *)line); - - return list; -} - -void sciw_set_status_bar(EngineState *s, GfxPort *status_bar, const Common::String &text, int fgcolor, int bgcolor) { - GfxState *state; - GfxList *list; - gfx_color_t bg = status_bar->_bgcolor; - gfx_color_t fg = status_bar->_color; - gfx_color_t black = s->ega_colors[0]; - - if (!status_bar->_visual) { - error("Attempt to change title bar without visual"); - return; - } - - state = status_bar->_visual->_gfxState; - - if (!state) { - error("Attempt to change title bar with stateless visual"); - return; - } - - clear_titlebar(status_bar); - - if (!text.empty()) { - GfxText *textw = gfxw_new_text(state, gfx_rect(0, 0, status_bar->_bounds.width, status_bar->_bounds.height), - status_bar->_font, text.c_str(), ALIGN_LEFT, ALIGN_CENTER, - fg, fg, bg, kFontNoNewlines); - - list = make_titlebar_list(s, status_bar->_bounds, status_bar); - - list->add((GfxContainer *)list, (GfxWidget *)textw); - - } else { - GfxBox *bgbox = gfxw_new_box(state, gfx_rect(0, 0, status_bar->_bounds.width, status_bar->_bounds.height - 1), - black, black, GFX_BOX_SHADE_FLAT); - - list = gfxw_new_list(status_bar->_bounds, 0); - - list->add((GfxContainer *)list, (GfxWidget *)bgbox); - } - - list->add((GfxContainer *)status_bar, list); - finish_titlebar_list(s, list, status_bar); - - status_bar->draw(gfxw_point_zero); - gfxop_update(state); -} - -static void sciw_make_window_fit(rect_t *rect, GfxPort *parent) { - // This window is meant to cover the whole screen, so we allow it to go through. - if (rect->width == 319 && rect->height == 189) - return; - - if (rect->x + rect->width > parent->_bounds.x + parent->_bounds.width) - rect->x -= (rect->x + rect->width) - (parent->_bounds.x + parent->_bounds.width) + 2; - - if (rect->y + rect->height > parent->_bounds.y + parent->_bounds.height) - rect->y -= (rect->y + rect->height) - (parent->_bounds.y + parent->_bounds.height) + 2; -} - -GfxPort *sciw_new_window(EngineState *s, - rect_t area, int font, - gfx_color_t color, gfx_color_t bgcolor, - int title_font, gfx_color_t title_color, gfx_color_t title_bgcolor, - const char *title, int flags) { - GfxVisual *visual = s->visual; - GfxState *state = s->gfx_state; - int shadow_offset = 2; - rect_t frame; - gfx_color_t black; - gfxop_set_color(state, &black, 0, 0, 0, 0, 0, 0); - GfxPort *win; - GfxList *decorations; -// int xextra = !(flags & kWindowNoFrame) ? 1 : 0; -// int yextra = !(flags & kWindowNoFrame) ? 2 : 0; - - if (area.width == 319 && area.height == 189) { - flags |= kWindowNoFrame; - // The below line makes the points bar in QfG2 work, but breaks - // the one in QfG1. Hm. - if ((byte)bgcolor.priority == 255) /* Yep, QfG2 */ - area.y += 3; - } - - /* - if (area.y + area.height > visual->_bounds.y + visual->_bounds.height) { - area.y -= (area.y + area.height) - (visual->_bounds.y + visual->_bounds.height) + yextra; - } - - if (area.x + area.width > visual->_bounds.x + visual->_bounds.width) { - area.x -= (area.x + area.width) - (visual->_bounds.x + visual->_bounds.width) + xextra; - } - */ - - if (flags & kWindowTitle) - area. y += 10; - - if (!(flags & (kWindowTitle | kWindowNoFrame))) - area.height -= 1; // Normal windows are drawn one pixel too small. - - sciw_make_window_fit(&area, s->wm_port); - win = new GfxPort(visual, area, color, bgcolor); - - win->_font = font; - win->_title_text = title ? title : ""; - win->port_flags = flags; - - win->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - - if (flags & kWindowDontDraw) - flags = kWindowTransparent | kWindowNoFrame; - - if (flags == (kWindowTransparent | kWindowNoFrame)) - return win; // Fully transparent window - - if (flags & kWindowTitle) - frame = gfx_rect(area.x - 1, area.y - 10, area.width + 2, area.height + 11); - else - frame = gfx_rect(area.x - 1, area.y - 1, area.width + 2, area.height + 2); - - // Set visible window boundaries - win->_bounds = gfx_rect(frame.x, frame.y, frame.width + shadow_offset, frame.height + shadow_offset); - - decorations = gfxw_new_list(gfx_rect(frame.x, frame.y, frame.width + 1 + shadow_offset, frame.height + 1 + shadow_offset), 0); - - if (!(flags & kWindowTransparent)) { - // Draw window background - win->port_bg = (GfxWidget *)gfxw_new_box(state, gfx_rect(1, (flags & kWindowTitle) ? 10 : 1, - area.width, area.height), bgcolor, bgcolor, GFX_BOX_SHADE_FLAT); - decorations->add((GfxContainer *)decorations, win->port_bg); - win->_flags |= GFXW_FLAG_OPAQUE; - } - - if (flags & kWindowTitle) { - // Add window title - rect_t title_rect = gfx_rect(1, 1, area.width, 8); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_box(state, title_rect, title_bgcolor, title_bgcolor, GFX_BOX_SHADE_FLAT)); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_text(state, title_rect, title_font, title, ALIGN_CENTER, ALIGN_CENTER, title_color, title_color, - title_bgcolor, kFontNoNewlines)); - } - - if (!(flags & kWindowNoFrame)) { - // Draw backdrop shadow - - if (!(flags & kWindowNoDropShadow)) { - gfxop_set_color(state, &black, 0, 0, 0, 0x80, bgcolor.priority, -1); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_box(state, gfx_rect(shadow_offset + 1, frame.height - 1, - frame.width - 4, shadow_offset), black, black, GFX_BOX_SHADE_FLAT)); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_box(state, gfx_rect(frame.width - 1, shadow_offset + 1, - shadow_offset, frame.height - 2), black, black, GFX_BOX_SHADE_FLAT)); - } - - // Draw frame - - gfxop_set_color(state, &black, 0, 0, 0, 0, bgcolor.priority, -1); - - if (!(flags & kWindowNoDropShadow)) { - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_rect(gfx_rect(0, 0, frame.width - 1, frame.height - 1), black, GFX_LINE_MODE_FINE, GFX_LINE_STYLE_NORMAL)); - - if (flags & kWindowTitle) - decorations->add((GfxContainer *)decorations, (GfxWidget *)gfxw_new_line(Common::Point(1, 9), - Common::Point(frame.width - 2, 9), black, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } else { - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_rect(gfx_rect(0, 0, frame.width, frame.height), black, GFX_LINE_MODE_FINE, GFX_LINE_STYLE_NORMAL)); - } - } - - win->_decorations = decorations; - decorations->_parent = (GfxContainer *)win; - - return win; -} - -//*** Controls *** - -static rect_t _move_and_extend_rect(rect_t rect, Common::Point point, int yplus) { - return gfx_rect(rect.x + point.x, rect.y + point.y, rect.width + 1, rect.height + yplus); -} - -GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, const char *text, - int font, gfx_alignment_t align, char framed, char inverse, int flags, char gray_text) { - gfx_color_t *color1, *color2, *bgcolor; - - if (inverse) { - color1 = color2 = &(port->_bgcolor); - bgcolor = &(port->_color); - } else if (gray_text) { - bgcolor = color1 = &(port->_bgcolor); - color2 = &(port->_color); - } else { - color1 = color2 = &(port->_color); - bgcolor = &(port->_bgcolor); - } - - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, zone, font, text, align, ALIGN_TOP, - *color1, *color2, *bgcolor, flags)); - - zone.width--; - zone.height -= 2; - - if (framed) { - list->add((GfxContainer *)list, gfxw_new_rect(zone, *color2, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_STIPPLED)); - } - - return list; -} - -GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, char selected, char inverse, char grayed_out) { - gfx_color_t *frame_col = (inverse) ? &(port->_bgcolor) : &(port->_color); - GfxList *list; - - zone.x--; - zone.y--; - zone.width++; - zone.height++; - - list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - - gfxw_set_id(list, ID.segment, ID.offset); - - zone.x = 0; - zone.y = 0; - - if (!inverse) { - list = _sciw_add_text_to_list(list, port, gfx_rect(zone.x + 1, zone.y + 2, zone.width - 1, zone.height), - text, font, ALIGN_CENTER, 0, inverse, kFontIgnoreLF, grayed_out); - - list->add((GfxContainer *)list, - gfxw_new_rect(zone, *frame_col, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } else { - list->add((GfxContainer *)list, gfxw_new_box(NULL, gfx_rect(zone.x, zone.y, zone.width + 1, zone.height + 1), - port->_color, port->_color, GFX_BOX_SHADE_FLAT)); - - list = _sciw_add_text_to_list(list, port, gfx_rect(zone.x + 1, zone.y + 2, zone.width - 1, zone.height), - text, font, ALIGN_CENTER, 0, inverse, kFontIgnoreLF, grayed_out); - } - - if (selected) - list->add((GfxContainer *)list, - gfxw_new_rect(gfx_rect(zone.x + 1, zone.y + 1, zone.width - 2, zone.height - 2), - *frame_col, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - - return list; -} - -GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, - gfx_alignment_t align, char framed, char inverse) { - GfxList *list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 2), 0); - - gfxw_set_id(list, ID.segment, ID.offset); - - zone.x = 0; - zone.y = 0; - - return _sciw_add_text_to_list(list, port, zone, text, font, align, framed, inverse, 0, port->gray_text); -} - -GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, unsigned int cursor, - char inverse) { - GfxText *text_handle; - - GfxList *list; - int cursor_height = port->_visual->_gfxState->gfxResMan->getFont(font)->line_height; - - zone.x--; - zone.y--; - zone.width++; - zone.height++; - - list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - gfxw_set_id(list, ID.segment, ID.offset); - zone.x = 1; - zone.y = 1; - - if ((g_system->getMillis() % 1000) < 500) { - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, text, ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines); - - list->add((GfxContainer *)list, text_handle); - } else { - char *textdup = (char *)malloc(strlen(text) + 1); - - strncpy(textdup, text, cursor); - - if (cursor <= strlen(text)) - textdup[cursor] = 0; // terminate - - if (cursor > 0) { - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, textdup, ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines); - - list->add((GfxContainer *)list, text_handle); - zone.x += text_handle->width; - } - - if (cursor < strlen(text)) { - textdup[0] = text[cursor]; - textdup[1] = 0; - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, textdup, ALIGN_LEFT, ALIGN_TOP, - port->_bgcolor, port->_bgcolor, port->_color, kFontNoNewlines); - list->add((GfxContainer *)list, text_handle); - zone.x += text_handle->width; - }; - - if (cursor + 1 < strlen(text)) { - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, text + cursor + 1, ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines); - list->add((GfxContainer *)list, text_handle); - zone.x += text_handle->width; - }; - - if (cursor == strlen(text)) - list->add((GfxContainer *)list, gfxw_new_line(Common::Point(zone.x, zone.y), Common::Point(zone.x, zone.y + cursor_height - 1), - port->_color, GFX_LINE_MODE_FAST, GFX_LINE_STYLE_NORMAL)); - free(textdup); - } - - zone.x = zone.y = 0; - - list->add((GfxContainer *)list, gfxw_new_rect(zone, port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - - return list; -} - -GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, int view, int loop, int cel, - char frame, char inverse) { - GfxList *list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - GfxWidget *icon; - gfxw_set_id(list, ID.segment, ID.offset); - - if (!port->_visual) { - error("Attempting to create icon control for virtual port"); - return NULL; - } - - zone.x = 0; - zone.y = 0; - - icon = gfxw_new_view(port->_visual->_gfxState, Common::Point(zone.x, zone.y), view, loop, cel, 0, -1, -1, - ALIGN_LEFT, ALIGN_TOP, GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET); - - if (!icon) { - error("Attempt to create icon control with cel %d/%d/%d (invalid)", view, loop, cel); - return NULL; - } - - list->_flags |= GFXW_FLAG_MULTI_ID; - - list->add((GfxContainer *)list, icon); - - return list; -} - -GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, const char **entries_list, - int entries_nr, int list_top, int selection, char inverse) { - GfxList *list; - - char arr_up[2], arr_down[2]; - int i; - - int font_height; - int columns; - - zone.x--; - zone.y--; - zone.width++; - zone.height++; - - list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - - font_height = port->_visual->_gfxState->gfxResMan->getFont(font_nr)->line_height; - columns = (zone.height - 20); - - columns /= font_height; - - gfxw_set_id(list, ID.segment, ID.offset); - - arr_up[0] = SCI_SPECIAL_CHAR_ARROW_UP; - arr_down[0] = SCI_SPECIAL_CHAR_ARROW_DOWN; - arr_up[1] = arr_down[1] = 0; - - zone.x = 1; - zone.y = 11; - - // Draw text - - for (i = list_top; columns-- && i < entries_nr; i++) { - if (i != selection) - list->add((GfxContainer *)list, - gfxw_new_text(port->_visual->_gfxState, gfx_rect(zone.x, zone.y, zone.width - 2, font_height), - font_nr, entries_list[i], ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines)); - else { - list->add((GfxContainer *)list, gfxw_new_box(port->_visual->_gfxState, gfx_rect(zone.x, zone.y, zone.width - 1, font_height), - port->_color, port->_color, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, gfx_rect(zone.x, zone.y, zone.width - 2, font_height), - font_nr, entries_list[i], ALIGN_LEFT, ALIGN_TOP, - port->_bgcolor, port->_bgcolor, port->_color, kFontNoNewlines)); - } - - zone.y += font_height; - } - - // Draw frames - - zone.x = 0; - zone.y = 0; - - // Add up arrow - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, gfx_rect(1, 0, zone.width - 2, 8), - port->_font, arr_up, ALIGN_CENTER, ALIGN_CENTER, - port->_color, port->_color, port->_bgcolor, 0)); - - // Add down arrow - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, gfx_rect(1, zone.height - 9, zone.width - 2, 8), - port->_font, arr_down, ALIGN_CENTER, ALIGN_CENTER, - port->_color, port->_color, port->_bgcolor, 0)); - - if (list_top & 1) { // Hack to work around aggressive caching - list->add((GfxContainer *)list, gfxw_new_rect(zone, port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - list->add((GfxContainer *)list, gfxw_new_rect(gfx_rect(zone.x, zone.y + 10, zone.width, zone.height - 20), - port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } else { - list->add((GfxContainer *)list, - gfxw_new_rect(gfx_rect(zone.x, zone.y, zone.width, zone.height - 10), - port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - list->add((GfxContainer *)list, - gfxw_new_rect(gfx_rect(zone.x, zone.y + 10, zone.width, zone.height - 10), - port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } - - return list; -} - -void sciw_set_menubar(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection) { - GfxList *list = make_titlebar_list(s, status_bar->_bounds, status_bar); - int offset = MENU_LEFT_BORDER; - int i; - - clear_titlebar(status_bar); - - for (i = 0; i < (int)menubar->_menus.size(); i++) { - Menu *menu = &menubar->_menus[i]; - int width = menu->_titleWidth + (MENU_BORDER_SIZE * 2); - - if (i == selection) { - list->add((GfxContainer *)list, gfxw_new_box(status_bar->_visual->_gfxState, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT), - status_bar->_color, status_bar->_color, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_text(s->gfx_state, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT), - status_bar->_font, menu->_title.c_str(), ALIGN_CENTER, ALIGN_CENTER, - status_bar->_bgcolor, status_bar->_bgcolor, status_bar->_color, kFontNoNewlines)); - } else - list->add((GfxContainer *)list, gfxw_new_text(s->gfx_state, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT), - status_bar->_font, menu->_title.c_str(), ALIGN_CENTER, ALIGN_CENTER, - status_bar->_color, status_bar->_color, status_bar->_bgcolor, kFontNoNewlines)); - offset += width; - } - - status_bar->add((GfxContainer *)status_bar, list); - finish_titlebar_list(s, list, status_bar); -} - -GfxPort *sciw_new_menu(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection) { - GfxPort *retval; - Menu *menu = &menubar->_menus[selection]; - rect_t area = gfx_rect(MENU_LEFT_BORDER, 10, 0, 0); - int i; - - if (selection < -1) - return NULL; - - if (selection >= (int)menubar->_menus.size()) { - error("Attempt to make menu #%d of %d", selection, menubar->_menus.size()); - return NULL; - } - - for (i = 0; i < selection; i++) - area.x += menubar->_menus[i]._titleWidth; - - area.width = menu->_width - 1; - area.height = menu->_items.size() * 10; - - retval = sciw_new_window(s, area, status_bar->_font, status_bar->_color, status_bar->_bgcolor, - 0, status_bar->_color, status_bar->_bgcolor, NULL, kWindowNoDropShadow | kWindowTransparent); - - retval->setVisual(s->visual); - - for (i = 0; i < (int)menu->_items.size(); i++) - sciw_toggle_item(retval, menu, i, false); - - return retval; -} - -#define MAGIC_ID_OFFSET 0x2000 - -static gfx_color_t un_prioritize(gfx_color_t col) { - col.priority = -1; - col.mask &= ~GFX_MASK_PRIORITY; - - return col; -} - -GfxWidget *_make_menu_entry(MenuItem *item, int offset, int width, GfxPort *port, gfx_color_t color, gfx_color_t bgcolor, int ID, int gray) { - rect_t area = gfx_rect(MENU_BOX_LEFT_PADDING, 0, width - MENU_BOX_LEFT_PADDING, 10); - rect_t list_area = gfx_rect(port->zone.x, area.y + offset + port->zone.y, width, area.height); - GfxList *list = (GfxList *) gfxw_set_id(gfxw_new_list(list_area, 0), ID, GFXW_NO_ID); - gfx_color_t xcolor = { PaletteEntry(), 0, 0, 0, 0}; - - color = un_prioritize(color); - bgcolor = un_prioritize(bgcolor); - - xcolor = gray ? color : bgcolor; - - list->add((GfxContainer *)list, gfxw_new_box(port->_visual->_gfxState, area, bgcolor, bgcolor, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, area, port->_font, item->_text.c_str(), ALIGN_LEFT, ALIGN_CENTER, - color, xcolor, bgcolor, kFontNoNewlines)); - - if (!item->_keytext.empty()) { - area.width -= MENU_BOX_RIGHT_PADDING; - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, area, port->_font, item->_keytext.c_str(), ALIGN_RIGHT, ALIGN_CENTER, - color, xcolor, bgcolor, kFontNoNewlines)); - } - - return list; -} - -GfxWidget *_make_menu_hbar(int offset, int width, GfxPort *port, gfx_color_t color, gfx_color_t bgcolor, int ID) { - rect_t area = gfx_rect(0, 0, width, 10); - rect_t list_area = gfx_rect(area.x + port->zone.x, area.y + offset + port->zone.y, area.width, area.height); - GfxList *list = (GfxList *) gfxw_set_id(gfxw_new_list(list_area, 0), ID, GFXW_NO_ID); - - color = un_prioritize(color); - bgcolor = un_prioritize(bgcolor); - - list->add((GfxContainer *)list, gfxw_new_box(port->_visual->_gfxState, area, bgcolor, bgcolor, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_line(Common::Point(0, 5), Common::Point(width, 5), color, - GFX_LINE_MODE_FAST, GFX_LINE_STYLE_STIPPLED)); - - return list; -} - -GfxPort *sciw_toggle_item(GfxPort *menu_port, Menu *menu, int selection, bool selected) { - if (selection < 0 || selection >= (int)menu->_items.size()) - return menu_port; - - gfx_color_t fgColor = !selected ? menu_port->_color : menu_port->_bgcolor; - gfx_color_t bgColor = !selected ? menu_port->_bgcolor : menu_port->_color; - - MenuItem *item = &menu->_items[selection]; - - if (item->_type == MENU_TYPE_NORMAL) - menu_port->add((GfxContainer *)menu_port, _make_menu_entry(item, selection * 10, menu_port->zone.width + 1, - menu_port, fgColor, bgColor, selection + MAGIC_ID_OFFSET, item->_enabled)); - else - menu_port->add((GfxContainer *)menu_port, _make_menu_hbar(selection * 10, menu_port->zone.width + 1, - menu_port, fgColor, bgColor, selection + MAGIC_ID_OFFSET)); - - return menu_port; -} - -void _k_view_list_mark_free(EngineState *s, reg_t off) { - if (s->dyn_views) { - - GfxDynView *w = (GfxDynView *)s->dyn_views->_contents; - - while (w) { - if (w->_ID == off.segment - && w->_subID == off.offset) { - w->under_bitsp.obj = NULL_REG; - } - - w = (GfxDynView *)w->_next; - } - } -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_gui.h b/engines/sci/gfx/gfx_gui.h deleted file mode 100644 index be724ae873..0000000000 --- a/engines/sci/gfx/gfx_gui.h +++ /dev/null @@ -1,225 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_INCLUDE_SCI_WIDGETS_H -#define SCI_INCLUDE_SCI_WIDGETS_H - -#include "sci/engine/state.h" - -namespace Sci { - -class Menu; - -/* SCI-specific widget handling */ - -/** - * Flags for windows in SCI0. - */ -enum windowFlags { - kWindowTransparent = 0x01, ///< 0000 0001 - kWindowNoFrame = 0x02, ///< 0000 0010 - a window without a frame - kWindowTitle = 0x04, /** - * 0000 0100 - Add title bar to - * window (10 pixels high, framed, - * text is centered and written in - * white on dark gray), bits 3-6 - * are unused - */ - kWindowDontDraw = 0x80, ///< 1000 0000 - don't draw anything - kWindowNoDropShadow = 0x1000000, ///< 0001 0000 0000 0000 0000 0000 0000 (not in SCI) - kWindowAutoRestore = 0x2000000 -}; - -/** - * Sets the contents of a port used as status bar. - * - * @param[in] s The affected EngineState - * @param[in] status_bar The status bar port - * @param[in] text The text to draw - * @param[in] fgcolor The foreground color - * @param[in] bgcolor The background color - */ -void sciw_set_status_bar(EngineState *s, GfxPort *status_bar, - const Common::String &text, int fgcolor, int bgcolor); - -/** - * Creates a new SCI style window. - * - * @param[in] s The affected EngineState - * @param[in] area The screen area to frame (not including a - * potential window title) - * @param[in] font Default font number to use - * @param[in] color The foreground color to use for drawing - * @param[in] bgcolor The background color to use - * @param[in] title_font The font to use for the title bar (if any) - * @param[in] title_color Color to use for the title bar text - * @param[in] title_bg_color Color to use for the title bar background - * @param[in] title The text to write into the title bar - * @param[in] flags Any ORred combination of window flags - * @return A newly allocated port with the requested characteristics - */ -GfxPort *sciw_new_window(EngineState *s, rect_t area, int font, - gfx_color_t color, gfx_color_t bgcolor, int title_font, - gfx_color_t title_color, gfx_color_t title_bg_color, - const char *title, int flags); - - -/** @name Control widgets */ -/** @{ */ -/** - * Creates a new button control list. - * - * @param[in] port The port containing the color values to use for the - * button (the button is /not/ appended to the port - * there) - * @param[in] ID Button's ID - * @param[in] zone The area occupied by the button - * @param[in] text The text to write into the button - * @param[in] font The font to use for the button - * @param[in] selected Whether the button should be marked as being - * selected by the keyboard focus - * @param[in] inverse Whether to inverse the color scheme - * @param[in] gray Whether the button should be grayed out - * @return The button - */ -GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, - const char *text, int font, char selected, char inverse, char gray); - -/** - * Creates a new text control list. - * - * @param[in] port The port containing the color values to use - * @param[in] ID Text widget ID - * @param[in] zone Area occupied by the text - * @param[in] text The text - * @param[in] font The font the text is to be drawn in - * @param[in] align Horizontal text alignment to use - * @param[in] frame Whether a dithered frame should surround the text - * @param[in] inverse Whether the text colors should be inversed - * @return The text control widget list - */ -GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, - const char *text, int font, gfx_alignment_t align, char frame, - char inverse); - -/** - * Creates a new edit control list. - * - * @param[in] port The port containing the color values to use - * @param[in] ID Text widget ID - * @param[in] zone Area occupied by the text - * @param[in] text The text - * @param[in] font The font the text is to be drawn in - * @param[in] cursor Cursor position - * @param[in] inverse Whether the edit widget should be reversed - * @return An appropriate widget list - */ -GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, - const char *text, int font, unsigned int cursor, char inverse); - -/** - * Creates a new icon control list. - * - * @param[in] port The port containing the color values to use - * @param[in] ID Text widget ID - * @param[in] zone Area occupied by the text - * @param[in] view The view index - * @param[in] loop The loop index - * @param[in] cel The cel to display - * @param[in] frame Whether the widget should be surrounded by a frame - * @param[in] inverse Whether colors should be inversed - * @return An appropriate widget list - */ -GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, - int view, int loop, int cel, char frame, char inverse); - -/** - * Creates a new list control list. - * - * @param[in] port: The port containing the color values to use - * @param[in] ID: Text widget ID - * @param[in] zone: Area occupied by the text - * @param[in] font_nr: Number of the font to use - * @param[in] entries_list: List of strings to contain within the list - * @param[in] entries_nr: Number of entries in entries_list - * @param[in] list_top: First list item that is visible - * @param[in] selection: The list item that is selected - * @param[in] inverse: The usual meaning - * @return An appropriate widget list - */ -GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, - int font_nr, const char **entries_list, int entries_nr, - int list_top, int selection, char inverse); -/** @} */ - -/** @name Menubar widgets */ -/** @{ */ - -/** - * Draws the menu bar. - * - * @param[in] s: The EngineState to operate on - * @param[in] status_bar: The status bar port to modify - * @param[in] menubar: The menu bar to use - * @param[in] selection: Number of the menu to hightlight, or -1 for - * 'none' - */ -void sciw_set_menubar(EngineState *s, GfxPort *status_bar, Menubar *menubar, - int selection); - -/** - * Creates a menu port. - * - * @param[in] s The state to operate on - * @param[in] status_bar The status bar - * @param[in] menubar The menu bar to use - * @param[in] selection Number of the menu to interpret - * @return The result port - */ -GfxPort *sciw_new_menu(EngineState *s, GfxPort *status_bar, - Menubar *menubar, int selection); - -/** - * Toggle the selection of a menu item from a menu port. - * - * @param[in] menu_port The port to modify - * @param[in] menu The menu the menu port corresponds to - * @param[in] selection Number of the menu entry to unselect, or -1 to do - * a NOP - * @param[in] selected Whether to set the item's state to selected or not - * @return The modified menu - */ -GfxPort *sciw_toggle_item(GfxPort *menu_port, Menu *menu, int selection, - bool selected); -/** @} */ - -} // End of namespace Sci - -#endif // SCI_INCLUDE_SCI_WIDGETS_H - -#endif diff --git a/engines/sci/gfx/gfx_pixmap_scale.cpp b/engines/sci/gfx/gfx_pixmap_scale.cpp deleted file mode 100644 index d542683cee..0000000000 --- a/engines/sci/gfx/gfx_pixmap_scale.cpp +++ /dev/null @@ -1,133 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -/* Required defines: -** FUNCNAME: Function name -** SIZETYPE: Type used for each pixel -*/ - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - - -// TODO: Replace this code with our common scalers (/graphics/scaler.h) - - -static void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { - byte result_colors[GFX_PIC_COLORS]; - int scaleFactor = (scale) ? mode->scaleFactor : 1; - int widthc, heightc; // Width duplication counter - int line_width = scaleFactor * pxm->index_width; - int x, y; - int i; - byte byte_transparent = 0; - byte byte_opaque = 255; - byte *src = pxm->index_data; - byte *dest = pxm->data; - byte *alpha_dest = pxm->alpha_map; - int using_alpha = pxm->color_key != GFX_PIXMAP_COLOR_KEY_NONE; - int separate_alpha_map = using_alpha; - - if (separate_alpha_map && !alpha_dest) - alpha_dest = pxm->alpha_map = (byte *)malloc(pxm->index_width * scaleFactor * pxm->index_height * scaleFactor); - - // Calculate all colors - for (i = 0; i < pxm->colors_nr(); i++) - result_colors[i] = pxm->palette->getColor(i).getParentIndex(); - - if (!separate_alpha_map && pxm->color_key != GFX_PIXMAP_COLOR_KEY_NONE) - result_colors[pxm->color_key] = 0; - - src = pxm->index_data; // Workaround for gcc 4.2.3 bug on EMT64 - for (y = 0; y < pxm->index_height; y++) { - byte *prev_dest = dest; - byte *prev_alpha_dest = alpha_dest; - - for (x = 0; x < pxm->index_width; x++) { - int isalpha; - byte col = result_colors[isalpha = *src++]; - isalpha = (isalpha == pxm->color_key) && using_alpha; - - // O(n) loops. There is an O(ln(n)) algorithm for this, but its slower for small n (which we're optimizing for here). - // And, anyway, most of the time is spent in memcpy() anyway. - - for (widthc = 0; widthc < scaleFactor; widthc++) { - memcpy(dest, &col, 1); - dest++; - } - - if (separate_alpha_map) { // Set separate alpha map - memset(alpha_dest, (isalpha) ? byte_transparent : byte_opaque, scaleFactor); - alpha_dest += scaleFactor; - } - } - - // Copies each line. O(n) iterations; again, this could be optimized to O(ln(n)) for very high resolutions, - // but that wouldn't really help that much, as the same amount of data still would have to be transferred. - for (heightc = 1; heightc < scaleFactor; heightc++) { - memcpy(dest, prev_dest, line_width); - dest += line_width; - if (separate_alpha_map) { - memcpy(alpha_dest, prev_alpha_dest, line_width); - alpha_dest += line_width; - } - } - } - - pxm->width = pxm->index_width; - pxm->height = pxm->index_height; -} - - -void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode) { - if (pxm->palette && pxm->palette != mode->palette) - pxm->palette->mergeInto(mode->palette); - - if (!pxm->data) { - pxm->data = (byte*)malloc(mode->scaleFactor * mode->scaleFactor * pxm->index_width * pxm->index_height + 1); - // +1: Eases coying on BE machines in 24 bpp packed mode - // Assume that memory, if allocated already, will be sufficient - - // Allocate alpha map - if (pxm->colors_nr() < GFX_PIC_COLORS) - pxm->alpha_map = (byte*)malloc(mode->scaleFactor * mode->scaleFactor * pxm->index_width * pxm->index_height + 1); - } - - _gfx_xlate_pixmap_unfiltered(mode, pxm, false); - - if (pxm->palette) - pxm->palette_revision = pxm->palette->getRevision(); -} - - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp deleted file mode 100644 index f78f5980e9..0000000000 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ /dev/null @@ -1,532 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -// Resource manager core part - -// FIXME/TODO: The name "(Graphics) resource manager", and the associated -// filenames, are misleading. This should be renamed to "Graphics manager" -// or something like that. - -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gfx/gfx_resmgr.h" -#include "sci/gui/gui_palette.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_view.h" -#include "sci/gfx/gfx_driver.h" -#include "sci/gfx/gfx_state_internal.h" -#include "sci/gui32/font.h" - -#include "common/system.h" - -namespace Sci { - -struct param_struct { - int args[4]; - GfxDriver *driver; -}; - -GfxResManager::GfxResManager(GfxDriver *driver, ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, Common::Rect portBounds) : - _driver(driver), _resMan(resMan), _screen(screen), _palette(palette), - _lockCounter(0), _tagLockCounter(0), _staticPalette(0) { - gfxr_init_static_palette(); - - _portBounds = portBounds; - - if (!_resMan->isVGA()) { - _staticPalette = gfx_sci0_pic_colors->getref(); - } else if (getSciVersion() == SCI_VERSION_1_1) { - debugC(2, kDebugLevelGraphics, "Palettes are not yet supported in this SCI version\n"); -#ifdef ENABLE_SCI32 - } else if (getSciVersion() >= SCI_VERSION_2) { - debugC(2, kDebugLevelGraphics, "Palettes are not yet supported in this SCI version\n"); -#endif - } else { - Resource *res = resMan->findResource(ResourceId(kResourceTypePalette, 999), 0); - if (res && res->data) - _staticPalette = gfxr_read_pal1(res->id.number, res->data, res->size); - } -} - -GfxResManager::~GfxResManager() { - _staticPalette->free(); - _staticPalette = 0; -} - -void GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, int flags, int default_palette, int nr) { - Resource *res = _resMan->findResource(ResourceId(kResourceTypePic, nr), 0); - int need_unscaled = unscaled_pic != NULL; - gfxr_pic0_params_t style, basic_style; - - basic_style.line_mode = GFX_LINE_MODE_CORRECT; - basic_style.brush_mode = GFX_BRUSH_MODE_SCALED; - style.line_mode = GFX_LINE_MODE_CORRECT; - style.brush_mode = GFX_BRUSH_MODE_RANDOM_ELLIPSES; - - if (!res || !res->data) - error("calculatePic(): pic number %d not found", nr); - - if (need_unscaled) { - if (_resMan->getViewType() == kViewVga11) - gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _staticPalette, _portBounds); - else - gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _resMan->getViewType(), _staticPalette, _portBounds); - } - - if (scaled_pic && scaled_pic->undithered_buffer) - memcpy(scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer, scaled_pic->undithered_buffer_size); - - if (_resMan->getViewType() == kViewVga11) - gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _staticPalette, _portBounds); - else - gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _resMan->getViewType(), _staticPalette, _portBounds); - - if (getSciVersion() <= SCI_VERSION_1_EGA) { - if (need_unscaled) - gfxr_remove_artifacts_pic0(scaled_pic, unscaled_pic); - - if (!scaled_pic->undithered_buffer) - scaled_pic->undithered_buffer = malloc(scaled_pic->undithered_buffer_size); - - memcpy(scaled_pic->undithered_buffer, scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer_size); - - gfxr_dither_pic0(scaled_pic, kDitherNone); - } - - // Mark default palettes - if (scaled_pic) - scaled_pic->visual_map->loop = default_palette; - - if (unscaled_pic) - unscaled_pic->visual_map->loop = default_palette; -} - -#define FREEALL(freecmd, type) \ - if (resource->scaled_data.type) \ - freecmd(resource->scaled_data.type); \ - resource->scaled_data.type = NULL; \ - if (resource->unscaled_data.type) \ - freecmd(resource->unscaled_data.type); \ - resource->unscaled_data.type = NULL; - -void gfxr_free_resource(gfx_resource_t *resource, int type) { - if (!resource) - return; - - switch (type) { - - case GFX_RESOURCE_TYPE_VIEW: - FREEALL(gfxr_free_view, view); - break; - - case GFX_RESOURCE_TYPE_PIC: - FREEALL(gfxr_free_pic, pic); - break; - - case GFX_RESOURCE_TYPE_FONT: - FREEALL(gfxr_free_font, font); - break; - - case GFX_RESOURCE_TYPE_CURSOR: - FREEALL(gfx_free_pixmap, pointer); - break; - - default: - warning("[GFX] Attempt to free invalid resource type %d", type); - } - - free(resource); -} - -void GfxResManager::freeAllResources() { - for (int type = 0; type < GFX_RESOURCE_TYPES_NR; ++type) { - for (IntResMap::iterator iter = _resourceMaps[type].begin(); iter != _resourceMaps[type].end(); ++iter) { - gfxr_free_resource(iter->_value, type); - iter->_value = 0; - } - } -} - -void GfxResManager::freeResManager() { - freeAllResources(); - _lockCounter = _tagLockCounter = 0; -} - -void GfxResManager::freeTaggedResources() { - // Current heuristics: free tagged views and old pics - - IntResMap::iterator iter; - int type; - const int tmp = _tagLockCounter; - - type = GFX_RESOURCE_TYPE_VIEW; - for (iter = _resourceMaps[type].begin(); iter != _resourceMaps[type].end(); ++iter) { - gfx_resource_t *resource = iter->_value; - - if (resource) { - if (resource->lock_sequence_nr < tmp) { - gfxr_free_resource(resource, type); - iter->_value = 0; - } else { - resource->lock_sequence_nr = 0; - } - } - } - - type = GFX_RESOURCE_TYPE_PIC; - for (iter = _resourceMaps[type].begin(); iter != _resourceMaps[type].end(); ++iter) { - gfx_resource_t *resource = iter->_value; - - if (resource) { - if (resource->lock_sequence_nr < 0) { - gfxr_free_resource(resource, type); - iter->_value = 0; - } else { - resource->lock_sequence_nr--; - } - } - } - - _tagLockCounter = 0; -} - - -void GfxResManager::setStaticPalette(Palette *newPalette) -{ - if (_staticPalette) - _staticPalette->free(); - - _staticPalette = newPalette; - _staticPalette->name = "static palette"; - - if (_driver->getMode()->palette) - _staticPalette->mergeInto(_driver->getMode()->palette); -} - -#if 0 -// FIXME: the options for GFX_MASK_VISUAL are actually unused -#define XLATE_AS_APPROPRIATE(key, entry) \ - if (maps & key) { \ - if (res->unscaled_data.pic&& (force || !res->unscaled_data.pic->entry->data)) { \ - if (key == GFX_MASK_VISUAL) \ - gfx_get_res_config(options->res_conf, res->unscaled_data.pic->entry); \ - gfx_xlate_pixmap(res->unscaled_data.pic->entry, mode, filter); \ - } if (scaled && res->scaled_data.pic && (force || !res->scaled_data.pic->entry->data)) { \ - if (key == GFX_MASK_VISUAL) \ - gfx_get_res_config(options->res_conf, res->scaled_data.pic->entry); \ - gfx_xlate_pixmap(res->scaled_data.pic->entry, mode, filter); \ - } \ - } -#endif - -#define XLATE_AS_APPROPRIATE(key, entry) \ - if (maps & key) { \ - if (res->unscaled_data.pic&& (force || !res->unscaled_data.pic->entry->data)) { \ - gfx_xlate_pixmap(res->unscaled_data.pic->entry, mode); \ - } if (scaled && res->scaled_data.pic && (force || !res->scaled_data.pic->entry->data)) { \ - gfx_xlate_pixmap(res->scaled_data.pic->entry, mode); \ - } \ - } - -static gfxr_pic_t *gfxr_pic_xlate_common(gfx_resource_t *res, int maps, int scaled, int force, gfx_mode_t *mode) { - - XLATE_AS_APPROPRIATE(GFX_MASK_VISUAL, visual_map); - XLATE_AS_APPROPRIATE(GFX_MASK_PRIORITY, priority_map); - XLATE_AS_APPROPRIATE(GFX_MASK_CONTROL, control_map); - - return scaled ? res->scaled_data.pic : res->unscaled_data.pic; -} -#undef XLATE_AS_APPROPRIATE - -/* unscaled color index mode: Used in addition to a scaled mode -** to render the pic resource twice. -*/ -// FIXME: this is an ugly hack. Perhaps we could do it some other way? -gfx_mode_t mode_1x1_color_index = { /* Fake 1x1 mode */ - /* scaleFactor */ 1, - /* xsize */ 1, /* ysize */ 1, - /* palette */ NULL -}; - -gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_palette, bool scaled) { - gfxr_pic_t *npic = NULL; - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_PIC]; - gfx_resource_t *res = NULL; - int need_unscaled = (_driver->getMode()->scaleFactor != 1); - - res = resMap.contains(num) ? resMap[num] : NULL; - - if (!res) { - gfxr_pic_t *pic = NULL; - gfxr_pic_t *unscaled_pic = NULL; - - need_unscaled = 0; - pic = gfxr_init_pic(_driver->getMode(), GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resMan->isVGA()); - - if (!pic) { - error("Failed to allocate scaled pic"); - return NULL; - } - - gfxr_clear_pic0(pic, SCI_TITLEBAR_SIZE); - - if (need_unscaled) { - unscaled_pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resMan->isVGA()); - if (!unscaled_pic) { - error("Failed to allocate unscaled pic"); - return NULL; - } - gfxr_clear_pic0(pic, SCI_TITLEBAR_SIZE); - } - - calculatePic(pic, unscaled_pic, flags, default_palette, num); - - if (!res) { - res = (gfx_resource_t *)malloc(sizeof(gfx_resource_t)); - res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num); - res->lock_sequence_nr = 0; - resMap[num] = res; - } else { - gfxr_free_pic(res->scaled_data.pic); - if (res->unscaled_data.pic) - gfxr_free_pic(res->unscaled_data.pic); - } - - res->scaled_data.pic = pic; - res->unscaled_data.pic = unscaled_pic; - } else { - res->lock_sequence_nr = 0; - } - - npic = gfxr_pic_xlate_common(res, maps, 1, 0, _driver->getMode()); - - return npic; -} - -static void set_pic_id(gfx_resource_t *res, int id) { - if (res->scaled_data.pic) { - gfxr_pic_t *pic = res->scaled_data.pic; - pic->control_map->ID = id; - pic->priority_map->ID = id; - pic->visual_map->ID = id; - } - - if (res->unscaled_data.pic) { - gfxr_pic_t *pic = res->unscaled_data.pic; - pic->control_map->ID = id; - pic->priority_map->ID = id; - pic->visual_map->ID = id; - } -} - -static int get_pic_id(gfx_resource_t *res) { - if (res->scaled_data.pic) - return res->scaled_data.pic->visual_map->ID; - else - return res->unscaled_data.pic->visual_map->ID; -} - -gfxr_pic_t *GfxResManager::addToPic(int old_nr, int new_nr, int flags, int old_default_palette, int default_palette) { - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_PIC]; - gfxr_pic_t *pic = NULL; - gfx_resource_t *res = NULL; - int need_unscaled = 1; - - res = resMap.contains(old_nr) ? resMap[old_nr] : NULL; - - if (!res) { - getPic(old_nr, 0, flags, old_default_palette, 1); - - res = resMap.contains(old_nr) ? resMap[old_nr] : NULL; - - if (!res) { - warning("[GFX] Attempt to add pic %d to non-existing pic %d", new_nr, old_nr); - return NULL; - } - } - - // The following two operations are needed when returning scaled maps (which is always the case here) - res->lock_sequence_nr = 0; - calculatePic(res->scaled_data.pic, need_unscaled ? res->unscaled_data.pic : NULL, - flags | DRAWPIC01_FLAG_OVERLAID_PIC, default_palette, new_nr); - - { - int old_ID = get_pic_id(res); - set_pic_id(res, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, new_nr)); // To ensure that our graphical translation options work properly - pic = gfxr_pic_xlate_common(res, GFX_MASK_VISUAL, 1, 1, _driver->getMode()); - set_pic_id(res, old_ID); - } - - return pic; -} - -gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_VIEW]; - gfx_resource_t *res = resMap.contains(nr) ? resMap[nr] : NULL; - ViewType viewType = _resMan->getViewType(); - - gfxr_view_t *view = NULL; - gfxr_loop_t *loop_data = NULL; - gfx_pixmap_t *cel_data = NULL; - - if (!res) { - // Wrapper code for the new view decoder - view = (gfxr_view_t *)malloc(sizeof(gfxr_view_t)); - - view->ID = nr; - view->flags = 0; - - SciGuiView *guiView = new SciGuiView(_resMan, _screen, _palette, nr); - - // Translate view palette - view->palette = NULL; - - if (viewType == kViewVga || viewType == kViewVga11) { - GuiPalette *viewPalette = guiView->getPalette(); - if (viewPalette) { - view->palette = new Palette(256); - for (int c = 0; c < 256; c++) - view->palette->setColor(c, viewPalette->colors[c].r, viewPalette->colors[c].g, viewPalette->colors[c].b); - } - - // Assign missing colors from the view's palette to the global palette ones - for (unsigned i = 0; i < MIN(view->palette->size(), _staticPalette->size()); i++) { - const PaletteEntry& vc = view->palette->getColor(i); - if (vc.r == 0 && vc.g == 0 && vc.b == 0) { - const PaletteEntry& sc = _staticPalette->getColor(i); - view->palette->setColor(i, sc.r, sc.g, sc.b); - } - } - } else { - view->palette = _staticPalette->getref(); - } - - view->loops_nr = guiView->getLoopCount(); - view->loops = (gfxr_loop_t*)malloc(sizeof(gfxr_loop_t) * ((view->loops_nr) ? view->loops_nr : 1)); /* Alloc 1 if no loop */ - - for (int i = 0; i < view->loops_nr; i++) { - view->loops[i].cels_nr = guiView->getLoopInfo(i)->celCount; - view->loops[i].cels = (gfx_pixmap_t**)calloc(view->loops[i].cels_nr, sizeof(gfx_pixmap_t *)); - - for (int j = 0; j < view->loops[i].cels_nr; j++) { - sciViewCelInfo *celInfo = guiView->getCelInfo(i, j); - view->loops[i].cels[j] = gfx_pixmap_alloc_index_data(gfx_new_pixmap(celInfo->width, celInfo->height, nr, i, j)); - gfx_pixmap_t *curCel = view->loops[i].cels[j]; - curCel->color_key = celInfo->clearKey; - // old code uses malloc() here, so we do so as well, as the buffer will be freed with free() in gfx_free_pixmap - curCel->index_data = (byte *)malloc(celInfo->width * celInfo->height); - byte *tmpBuffer = guiView->getBitmap(i, j); - memcpy(curCel->index_data, tmpBuffer, celInfo->width * celInfo->height); - curCel->flags = 0; - curCel->width = celInfo->width; - curCel->height = celInfo->height; - curCel->index_width = celInfo->width; - curCel->index_height = celInfo->height; - curCel->palette_revision = -1; - curCel->xoffset = -celInfo->displaceX; - curCel->yoffset = -celInfo->displaceY; - curCel->palette = view->palette->getref(); - curCel->alpha_map = 0; // will be allocated by gfx_xlate_pixmap() - curCel->data = 0; // will be allocated by gfx_xlate_pixmap() - } - } - - delete guiView; - - if (!res) { - res = (gfx_resource_t *)malloc(sizeof(gfx_resource_t)); - res->scaled_data.view = NULL; - res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr); - res->lock_sequence_nr = _tagLockCounter; - resMap[nr] = res; - } else { - gfxr_free_view(res->unscaled_data.view); - } - - res->unscaled_data.view = view; - - } else { - res->lock_sequence_nr = _tagLockCounter; // Update lock counter - view = res->unscaled_data.view; - } - - *loop = CLIP<int>(*loop, 0, view->loops_nr - 1); - loop_data = view->loops + (*loop); - *cel = CLIP<int>(*cel, 0, loop_data->cels_nr - 1); - cel_data = loop_data->cels[*cel]; - - if (!cel_data->data) { - gfx_xlate_pixmap(cel_data, _driver->getMode()); - } - - return view; -} - -gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) { - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_FONT]; - gfx_resource_t *res = NULL; - - // Workaround: lsl1sci mixes its own internal fonts with the global - // SCI ones, so we translate them here, by removing their extra bits - if (!resMap.contains(num) && !_resMan->testResource(ResourceId(kResourceTypeFont, num))) - num = num & 0x7ff; - - res = resMap.contains(num) ? resMap[num] : NULL; - - if (!res) { - Resource *fontRes = _resMan->findResource(ResourceId(kResourceTypeFont, num), 0); - if (!fontRes || !fontRes->data) - return NULL; - - gfx_bitmap_font_t *font = gfxr_read_font(fontRes->id.number, fontRes->data, fontRes->size); - - if (!res) { - res = (gfx_resource_t *)malloc(sizeof(gfx_resource_t)); - res->scaled_data.font = NULL; - res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_FONT, num); - res->lock_sequence_nr = _tagLockCounter; - resMap[num] = res; - } else { - gfxr_free_font(res->unscaled_data.font); - } - - res->unscaled_data.font = font; - - return font; - } else { - res->lock_sequence_nr = _tagLockCounter; // Update lock counter - if (res->unscaled_data.pointer) - return res->unscaled_data.font; - else - return res->scaled_data.font; - } -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_resmgr.h b/engines/sci/gfx/gfx_resmgr.h deleted file mode 100644 index 5b3b728702..0000000000 --- a/engines/sci/gfx/gfx_resmgr.h +++ /dev/null @@ -1,289 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_RESMAN_H -#define SCI_GFX_GFX_RESMAN_H - -#include "common/hashmap.h" -#include "common/rect.h" - -// FIXME/TODO: The name "(Graphics) resource manager", and the associated -// filenames, are misleading. This should be renamed to "Graphics manager" -// or something like that. - -#include "sci/gfx/gfx_resource.h" - -#include "sci/resource.h" - -namespace Sci { - -struct gfx_bitmap_font_t; -class ResourceManager; -class SciGuiPalette; - -enum gfx_resource_type_t { - GFX_RESOURCE_TYPE_VIEW = 0, - GFX_RESOURCE_TYPE_PIC, - GFX_RESOURCE_TYPE_FONT, - GFX_RESOURCE_TYPE_CURSOR, - GFX_RESOURCE_TYPE_PALETTE, - /* FIXME: Add PAL resource */ - - GFX_RESOURCE_TYPES_NR /**< Number of resource types that are to be supported */ -}; - -#define GFX_RESOURCE_TYPE_0 GFX_RESOURCE_TYPE_VIEW - -#define GFXR_RES_ID(type, index) ((type) << 16 | (index)) -#define GFXR_RES_TYPE(id) (id >> 16) -#define GFXR_RES_NR(id) (id & 0xffff) - -/** Graphics resource */ -struct gfx_resource_t { - int ID; /**< Resource ID */ - int lock_sequence_nr; /**< See description of lock_counter in GfxResManager */ - - /** Scaled pic */ - union { - gfx_pixmap_t *pointer; - gfxr_view_t *view; - gfx_bitmap_font_t *font; - gfxr_pic_t *pic; - } scaled_data; - - /** Original pic */ - union { - gfx_pixmap_t *pointer; - gfxr_view_t *view; - gfx_bitmap_font_t *font; - gfxr_pic_t *pic; - } unscaled_data; - -}; - - -struct gfx_options_t; - -typedef Common::HashMap<int, gfx_resource_t *> IntResMap; - -/** Graphics resource manager */ -class GfxResManager { -public: - GfxResManager(GfxDriver *driver, ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, Common::Rect portBounds); - ~GfxResManager(); - - - /** - * 'Tags' all resources for deletion. - * - * Tagged resources are untagged if they are referenced. - */ - void tagResources() { _tagLockCounter++; } - - - /** - * Retrieves a font. - * - * @param[in] num The font number - * @param[in] scaled Whether the font should be font-scaled - * @return The appropriate font, or NULL on error - */ - gfx_bitmap_font_t *getFont(int num, bool scaled = false); - - - /** - * Retrieves a translated view cel. - * - * @param[in] nr The view number - * @param[in] loop Pointer to a variable containing the loop number - * @param[in] cel Pointer to a variable containing the cel number - * @param[in] palette The palette to use - * @return The relevant view, or NULL if nr was invalid - * loop and cel are given as pointers in order to - * allow the underlying variables to be modified - * if they are invalid (this is relevant for SCI - * version 0, where invalid loop and cel numbers - * have to be interpreted as 'maximum' or 'minimum' - * by the interpreter) - */ - gfxr_view_t *getView(int nr, int *loop, int *cel, int palette); - - - /** - * Retrieves a displayable (translated) pic resource. - * - * @param[in] num Number of the pic resource - * @param[in] maps The maps to translate (ORred GFX_MASK_*) - * @param[in] flags Interpreter-dependant pic flags - * @param[in] default_palette The default palette to use for drawing - * (if applicable) - * @param[in] scaled Whether to return the scaled maps, or - * the unscaled ones (which may be - * identical) for some special operations. - * @return The appropriate pic resource with all - * maps as index (but not neccessarily - * translated) data. - */ - gfxr_pic_t *getPic(int num, int maps, int flags, int default_palette, - bool scaled = false); - - - /** - * Retrieves a displayable (translated) pic resource written ontop of - * an existing pic. - * - * This function invalidates the cached pic pointed to by old_nr in the - * cache. While subsequent addToPic() writes will still modify the - * 'invalidated' pic, gfxr_get_pic() operations will cause it to be - * removed from the cache and to be replaced by a clean version. - * - * @param[in] old_nr Number of the pic resource to write on - * @param[in] new_nr Number of the pic resource that is to - * be added - * @param[in] flags Interpreter-dependant pic flags - * @param[in] old_default_palette The default palette of the pic before - * translation - * @param[in] default_palette The default palette to use for drawing - * (if applicable) - * @return The appropriate pic resource with all - * maps as index (but not neccessarily - * translated) data. - */ - gfxr_pic_t *addToPic(int old_nr, int new_nr, int flags, - int old_default_palette, int default_palette); - - /** - * Calculate a picture - * - * @param[in] scaled_pic The pic structure that is to be - * written to - * @param[in] unscaled_pic The pic structure the unscaled pic is - * to be written to, or NULL if it isn't - * needed. - * @param[in] flags Pic drawing flags (interpreter - * dependant) - * @param[in] default_palette The default palette to use for pic - * drawing (interpreter dependant) - * @param[in] nr pic resource number - */ - void calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, - int flags, int default_palette, int nr); - - - /** - * Frees all resources currently allocated. - * - * This function is intended to be used primarily for debugging. - */ - void freeAllResources(); - - - /** - * Frees all tagged resources. - * - * Resources are tagged by calling gfx_tag_resources(), and untagged by - * calling the approprate dereferenciation function. - * Note that this function currently only affects view resources, as - * pic resources are treated differently, while font and cursor - * resources are relatively rare. - */ - void freeTaggedResources(); - - - /** - * Frees a previously allocated resource manager, and all allocated - * resources. - */ - void freeResManager(); - - /** - * Retrieves a color from the static palette - */ - const PaletteEntry &getColor(int color) { - return _staticPalette->getColor(color); - } - - /** - * Set static palette and merge it into the global palette - */ - void setStaticPalette(Palette *newPalette); - - /** - * Sets the picture port bounds - */ - void changePortBounds(int x1, int y1, int x2, int y2) { - _portBounds = Common::Rect(x1, y1, x2, y2); - } - -#if 0 - void setPaletteIntensity(int16 from, int16 to, int16 intensity) { - Palette *pal = _staticPalette->getref(); - - for (uint16 i = 0; i < _driver->getMode()->palette->size(); i++) { - byte r = pal->getColor(i).r * intensity / 100; - byte g = pal->getColor(i).g * intensity / 100; - byte b = pal->getColor(i).b * intensity / 100; - pal->makeSystemColor(i, PaletteEntry(r, g, b)); - } - pal->mergeInto(_driver->getMode()->palette); - _driver->install_palette(_driver, pal); - pal->unmerge(); - pal->free(); - } -#endif - - /** - * Gets the number of colors in the static palette. - * - * @return Number of pallete entries - */ - int getColorCount() { - return _staticPalette ? _staticPalette->size() : 0; - } - -private: - GfxDriver *_driver; - Palette *_staticPalette; - int _lockCounter; /**< Global lock counter; increased for each new - * resource allocated. The newly allocated resource will - * then be assigned the new value of the lock_counter, - * as will any resources referenced afterwards. */ - int _tagLockCounter; /**< lock counter value at tag time */ - Common::Rect _portBounds; - - IntResMap _resourceMaps[GFX_RESOURCE_TYPES_NR]; - ResourceManager *_resMan; - SciGuiScreen *_screen; - SciGuiPalette *_palette; -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_RESMAN_H - -#endif diff --git a/engines/sci/gfx/gfx_resource.cpp b/engines/sci/gfx/gfx_resource.cpp deleted file mode 100644 index 4a39b0d385..0000000000 --- a/engines/sci/gfx/gfx_resource.cpp +++ /dev/null @@ -1,78 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - -static void gfxr_free_loop(gfxr_loop_t *loop) { - int i; - - if (loop->cels) { - for (i = 0; i < loop->cels_nr; i++) - if (loop->cels[i]) - gfx_free_pixmap(loop->cels[i]); - - free(loop->cels); - } -} - -void gfxr_free_view(gfxr_view_t *view) { - int i; - - if (view->palette) - view->palette->free(); - - if (view->loops) { - for (i = 0; i < view->loops_nr; i++) - gfxr_free_loop(view->loops + i); - - free(view->loops); - } - free(view); -} - -void gfxr_free_pic(gfxr_pic_t *pic) { - gfx_free_pixmap(pic->visual_map); - gfx_free_pixmap(pic->priority_map); - gfx_free_pixmap(pic->control_map); - pic->visual_map = NULL; - pic->priority_map = NULL; - pic->control_map = NULL; - free(pic->priorityTable); - pic->priorityTable = NULL; - free(pic->undithered_buffer); - pic->undithered_buffer = 0; - free(pic); -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h deleted file mode 100644 index d3f1c727a5..0000000000 --- a/engines/sci/gfx/gfx_resource.h +++ /dev/null @@ -1,289 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -/** @file gfx_resource.h - * SCI Resource library. - */ - -#ifndef SCI_GFX_GFX_RESOURCE_H -#define SCI_GFX_GFX_RESOURCE_H - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_driver.h" -#include "sci/gui/gui_helpers.h" - -#include "common/rect.h" - -namespace Common { - class File; -} - -namespace Sci { - -/*** Styles for pic0 drawing ***/ -/* Dithering modes for SCI0 games */ -enum DitherMode { - kDitherNone = 0, // No dithering - kDither16Colors = 1, // Sierra SCI style - kDither256Colors = 2 // Enhanced style -}; - -#define SCI_TITLEBAR_SIZE 10 - -#define DRAWPIC01_FLAG_FILL_NORMALLY 1 -#define DRAWPIC01_FLAG_OVERLAID_PIC 2 -#define DRAWPIC1_FLAG_MIRRORED 4 - -#define GFXR_AUX_MAP_SIZE (320*200) - - -#define GFX_SCI0_IMAGE_COLORS_NR 16 -#define GFX_SCI0_PIC_COLORS_NR 256 - -#define GFX_SCI1_AMIGA_COLORS_NR 32 - -extern int sci0_palette; - -/** The 16 EGA base colors */ -extern Palette* gfx_sci0_image_pal[]; -extern PaletteEntry gfx_sci0_image_colors[][16]; - -/** - * The 256 interpolated colors (initialized when gfxr_init_pic() is called - * for the first time, or when gfxr_init_static_palette() is called) - */ -extern Palette* gfx_sci0_pic_colors; - -struct gfxr_pic0_params_t { - gfx_line_mode_t line_mode; /* one of GFX_LINE_MODE_* */ - gfx_brush_mode_t brush_mode; -}; - -/** A SCI resource pic */ -struct gfxr_pic_t { - int ID; /**< pic number (NOT resource ID, just number) */ - gfx_mode_t *mode; - gfx_pixmap_t *visual_map; /**< Visual part of pic */ - gfx_pixmap_t *priority_map; /**< Priority map for pic */ - gfx_pixmap_t *control_map; /**< Control map for pic */ - - /** - * Auxiliary map. - * Bit 0: Vis - * Bit 1: Pri - * Bit 2: Ctrl - * Bit 3-5: 'filled' (all three bits are set to 1) - */ - byte aux_map[GFXR_AUX_MAP_SIZE]; - - // rect_t bounds; // unused - - void *undithered_buffer; /**< copies visual_map->index_data before dithering */ - int undithered_buffer_size; - - int *priorityTable; -}; - -/** A animation loop */ -struct gfxr_loop_t { - int cels_nr; /**< Number of 'cels' or frames in the animation */ - gfx_pixmap_t **cels; /**< Pointer to the pixmaps for the cels */ -}; - -/** A graphics view */ -struct gfxr_view_t { - int ID; - - int flags; - Palette *palette; - - int loops_nr; - gfxr_loop_t *loops; -}; - -/** - * Initializes the static 256 color palette. - */ -void gfxr_init_static_palette(); - -/** @name Resource picture management functions */ -/** @{ */ - -/** - * Initializes a gfxr_pic_t for a specific mode. - * - * This function allocates memory for use by resource drawer functions. - * - * @param[in] mode The specific graphics mode - * @param[in] ID The ID to assign to the resulting pixmaps - * @param[in] sci1 true if a SCI1 pic, false otherwise - * @return The allocated pic resource, or NULL on error. - */ -gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, bool sci1); - -/** - * Uninitializes a pic resource. - * - * @param[in] pic The pic to free - */ -void gfxr_free_pic(gfxr_pic_t *pic); - -/** - * Frees all memory associated with a view. - * - * @param[in] view The view to free - */ -void gfxr_free_view(gfxr_view_t *view); -/** @} */ -/** @name SCI0 resource picture operations */ -/** @{ */ - -/** - * Clears all pic buffers of one pic/ - * - * This function should be called before gfxr_draw_pic0, unless cumulative - * drawing is intended - * - * @param[in] pic The picture to clear - * @param[in] titlebar_size How much space to reserve for the title bar - */ -void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size); - -/** - * Draws a pic resource (all formats prior to SCI1.1). - * - * The result is stored in gfxr_visual_map, gfxr_priority_map, and - * gfxr_control_map. The palette entry of gfxr_visual_map is never used. - * Note that the picture will not be drawn dithered; use gfxr_dither_pic0 - * for that. - * - * @param[in] pic The pic to draw to - * @param[in] fill_normally If 1, the pic is drawn normally; if 0, all - * fill operations will fill with black - * @param[in] default_palette The default palette to use for drawing - * @param[in] size Resource size - * @param[in] resource Pointer to the resource data - * @param[in] style The drawing style - * @param[in] resid The resource ID - * @param[in] viewType The view type for embedded views - * @param[in] static_pal The static palette - * @param[in] portBounds The bounds of the port being drawn to - */ -void gfxr_draw_pic01(gfxr_pic_t *pic, int fill_normally, - int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, ViewType viewType, - Palette *static_pal, Common::Rect portBounds); - -/** - * Draws a pic resource (SCI1.1). - * - * The result is stored in gfxr_visual_map, gfxr_priority_map, and - * gfxr_control_map. The palette entry of gfxr_visual_map is never used. - * Note that the picture will not be drawn dithered; use gfxr_dither_pic11 - * for that. - * - * @param[in] pic The pic to draw to - * @param[in] fill_normally If 1, the pic is drawn normally; if 0, all - * fill operations will fill with black - * @param[in] default_palette The default palette to use for drawing - * @param[in] size Resource size - * @param[in] resource Pointer to the resource data - * @param[in] style The drawing style - * @param[in] resid The resource ID - * @param[in] static_pal The static palette - * @param[in] portBounds Bounds of the port being drawn to - */ -void gfxr_draw_pic11(gfxr_pic_t *pic, int fill_normally, - int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, Palette *static_pal, - Common::Rect portBounds); - -/** - * Removes artifacts from a scaled pic. - * - * Using information from the (correctly rendered) src pic, this function - * implements some heuristics to remove artifacts from dest. Must be used - * before dither_pic0 is called, because it operates on the index buffer. - * - * @param[in] dest The scaled pic - * @param[in] src An unscaled pic - */ -void gfxr_remove_artifacts_pic0(gfxr_pic_t *dest, gfxr_pic_t *src); - -/** - * Dithers a gfxr_visual_map. - * - * @param[in] pic The pic to dither - * @param[DitherMode] mode The dithering mode to use - */ -void gfxr_dither_pic0(gfxr_pic_t *pic, DitherMode mode); - -/** @} */ - - -/** @name SCI1/1.1 resource picture operations */ -/** @{ */ - -/** - * Reads an SCI1 palette. - * - * @param[in] id Resource ID for the palette (or the view it was - * found in) - * @param[in] resource Source data - * @param[in] size Size of the memory block pointed to by resource - * @return Palette with the colors - */ -Palette *gfxr_read_pal1(int id, byte *resource, int size); - -/** - * Reads an SCI1 palette. - * - * @param[in] file Palette file - * @return Palette with the colors - */ -Palette *gfxr_read_pal1_amiga(Common::File &file); - -/** - * Reads an SCI1.1 palette. - * - * @param[in] id Resource ID for the palette (or the view it was - * found in) - * @param[in] resource Source data - * @param[in] size Size of the memory block pointed to by resource - * @return Palette with the colors - */ -Palette *gfxr_read_pal11(int id, byte *resource, int size); - -gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, ViewType viewType); -/** @} */ - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_RESOURCE_H - -#endif diff --git a/engines/sci/gfx/gfx_state_internal.h b/engines/sci/gfx/gfx_state_internal.h deleted file mode 100644 index ec8219dc46..0000000000 --- a/engines/sci/gfx/gfx_state_internal.h +++ /dev/null @@ -1,417 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_STATE_INTERNAL_H -#define SCI_GFX_GFX_STATE_INTERNAL_H - -#include "sci/engine/vm.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gfx/operations.h" -#include "sci/gfx/gfx_resmgr.h" -#include "sci/gfx/gfx_system.h" - -namespace Sci { - -enum gfxw_flag_t { - GFXW_FLAG_VISIBLE = (1<<0), - GFXW_FLAG_OPAQUE = (1<<1), - GFXW_FLAG_CONTAINER = (1<<2), - GFXW_FLAG_DIRTY = (1<<3), - GFXW_FLAG_TAGGED = (1<<4), - GFXW_FLAG_MULTI_ID = (1<<5), /**< Means that the ID used herein may be used more than once, i.e. is not unique */ - GFXW_FLAG_IMMUNE_TO_SNAPSHOTS = (1<<6), /**< Snapshot restoring doesn't kill this widget, and +5 bonus to saving throws vs. Death Magic */ - GFXW_FLAG_NO_IMPLICIT_SWITCH = (1<<7) /**< Ports: Don't implicitly switch to this port when disposing windows */ -}; - -struct gfxw_snapshot_t { - int serial; /**< The first serial number to kill */ - rect_t area; -}; - -enum gfxw_widget_type_t { - GFXW_, /**< Base widget */ - - GFXW_BOX, - GFXW_RECT, - GFXW_LINE, /* For lines, the bounding rectangle's xl, yl determine the line's expansion: - ** (x2, y2) = (x+xl, y+yl) */ - GFXW_VIEW, - GFXW_STATIC_VIEW, - GFXW_DYN_VIEW, - GFXW_PIC_VIEW, - GFXW_TEXT, - - GFXW_CONTAINER, - - GFXW_LIST, - GFXW_SORTED_LIST, - GFXW_VISUAL, - GFXW_PORT -}; - - -#define GFXW_MAGIC_VALID 0xC001 -#define GFXW_MAGIC_INVALID 0xbad - -#define GFXW_NO_ID -1 - -struct GfxWidget; -struct GfxContainer; -struct GfxVisual; -struct GfxPort; - -typedef int gfxw_bin_op(GfxWidget *, GfxWidget *); - -/** SCI graphics widget */ -struct GfxWidget { -public: - int _magic; /**< Extra check after typecasting */ - int _serial; /**< Serial number */ - int _flags; /**< Widget flags */ - gfxw_widget_type_t _type; - rect_t _bounds; /**< Boundaries */ - GfxWidget *_next; /**< Next widget in widget list */ - int _ID; /**< Unique ID or GFXW_NO_ID */ - int _subID; /**< A 'sub-ID', or GFXW_NO_ID */ - GfxContainer *_parent; /**< The parent widget, or NULL if not owned */ - GfxVisual *_visual; /**< The owner visual */ - int _widgetPriority; /**< Drawing priority, or -1 */ - -public: - GfxWidget(gfxw_widget_type_t type); - - /** - * The widget automatically removes itself from its owner, if it has one. - * Deleting a container will recursively free all of its contents. - */ - virtual ~GfxWidget(); - - /** - * Draws the widget. - * - * The widget is drawn iff it is flagged as dirty. Invoking this operation - * on a container widget will recursively draw all of its contents. - * - * @param[in] pos The position to draw to (added to the widget's - * internal position) - */ - virtual int draw(const Common::Point &pos) = 0; - - /** - * Tags the specified widget. - * - * If invoked on a container widget, this will also tag all of the - * container's contents (but not the contents' contents!) - * FIXME: Actually, the code in GfxContainer::tag contradicts the last - * claim! - */ - virtual void tag() { - _flags |= GFXW_FLAG_TAGGED; - } - - /** - * Prints a string representation of the widget with printf. - * - * Will recursively print all of the widget's contents if the widget - * contains further sub-widgets - * - * @param[in] indentation Number of double spaces to indent - */ - virtual void print(int indentation) const; - - /** - * Compares two comparable widgets by their screen position. - * - * This comparison only applies to some widgets; compare_to(a,a)=0 is not - * guaranteed. It may be used for sorting for all widgets. - * - * @param other The other widget - * @return <0, 0, or >0 if other is, respectively, less than, equal - * to, or greater than self - */ - gfxw_bin_op *compare_to; - - /** - * Compares two compareable widgets for equality. - * - * This operation checks whether two widgets describe the same graphical - * data. It is used to determine whether a new widget should be discarded - * because it describes the same graphical data as an old widget that has - * already been drawn. For lists, it also checks whether all contents are - * in an identical order. - * - * @param[in] other The other widget - * @return false if the widgets are not equal, true if they match - */ - gfxw_bin_op *equals; - - /** - * Determine whether other should replace this even though they are - * equivalent. - * - * When 'equals' returns true, this means that no new widget will be added. - * However, in some cases newer widgets may contain information that should - * cause the older widget to be removed nonetheless; this is indicated by - * this function. - * - * @param[in] other The other widget - * @return false if this should be kept, true if this should be - * replaced by the 'other' - */ - gfxw_bin_op *should_replace; - - /** - * Tests whether drawing this after other would reduce all traces of - * other. - * - * /a superarea_of b <=> for each pixel of b there exists an opaque pixel - * in a at the same location - * - * @param[in] other The widget to compare for containment - * @return true if this is superarea_of other, false otherwise - */ - gfxw_bin_op *superarea_of; - - /** - * Sets the visual for the widget - * - * This function is called by container->add() and need not be invoked - * explicitly. It also makes sure that dirty rectangles are passed to - * parent containers. - * - * @param[in] visual GfxVisual to set for the widget - */ - virtual int setVisual(GfxVisual *visual); - -//protected: - void printIntern(int indentation) const; - -}; - - -#define GFXW_IS_BOX(widget) ((widget)->_type == GFXW_BOX) -/** SCI box widget */ -struct GfxBox : public GfxWidget { - gfx_color_t _color1, _color2; - gfx_box_shade_t _shadeType; - -public: - GfxBox(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - - -#define GFXW_IS_PRIMITIVE(widget) ((widget)->_type == GFXW_RECT || (widget)->_type == GFXW_LINE) -/** SCI graphics primitive */ -struct GfxPrimitive : public GfxWidget { - gfx_color_t _color; - gfx_line_mode_t _lineMode; - gfx_line_style_t _lineStyle; - -public: - GfxPrimitive(rect_t area, gfx_color_t color, gfx_line_mode_t mode, - gfx_line_style_t style, gfxw_widget_type_t type); -}; - - - -#define GFXW_IS_VIEW(widget) ((widget)->_type == GFXW_VIEW || (widget)->_type == GFXW_STATIC_VIEW \ - || (widget)->_type == GFXW_DYN_VIEW || (widget)->_type == GFXW_PIC_VIEW) -/** SCI graphics view */ -struct GfxView : public GfxWidget { - Common::Point _pos; /**< Implies the value of 'bounds' in GfxWidget */ - gfx_color_t _color; - int _view, _loop, _cel; - int _palette; - -public: - GfxView(GfxState *state, Common::Point pos, int view_nr, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int flags); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -#define GFXW_IS_DYN_VIEW(widget) ((widget)->_type == GFXW_DYN_VIEW || (widget)->_type == GFXW_PIC_VIEW) -/** SCI dynamic view */ -struct GfxDynView : public GfxView { - /* FIXME: This code is specific to SCI */ - rect_t draw_bounds; /* The correct position to draw to */ - ObjVarRef under_bitsp; - ObjVarRef signalp; - int under_bits, signal; - int _z; /**< The z coordinate: Added to y, but used for sorting */ - int sequence; /**< Sequence number: For sorting */ - int force_precedence; /**< Precedence enforcement variable for sorting- defaults to 0 */ - - bool _isDrawn; // FIXME: This is specific to GFXW_PIC_VIEW - -public: - GfxDynView(GfxState *state, Common::Point pos, int z, int view, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int sequence); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - - - -#define GFXW_IS_TEXT(widget) ((widget)->_type == GFXW_TEXT) -/** SCI text widget */ -struct GfxText : public GfxWidget { - int _font; - int lines_nr, lineheight, lastline_width; - Common::String _text; - gfx_alignment_t halign, valign; - gfx_color_t _color1, _color2, _bgcolor; - int _textFlags; - int width; /**< Real text width */ - int height; /**< Real text height */ - TextHandle *_textHandle; - -public: - GfxText(GfxState *state, rect_t area, int font, const char *text, gfx_alignment_t halign, - gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, gfx_color_t bgcolor, int text_flags); - - ~GfxText(); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - - -/* Container widgets */ - -typedef int gfxw_unary_container_op(GfxContainer *); -typedef int gfxw_container_op(GfxContainer *, GfxWidget *); -typedef int gfxw_rect_op(GfxContainer *, rect_t, int); - -/** SCI container widget */ -struct GfxContainer : public GfxWidget { - rect_t zone; /**< The writeable zone (absolute) for contained objects */ - DirtyRectList _dirtyRects; /**< List of dirty rectangles */ - GfxWidget *_contents; - GfxWidget **_nextpp; /**< Pointer to the 'next' pointer in the last entry in contents */ - -public: - // TODO: Replace the following with virtual methods - gfxw_unary_container_op *free_tagged; /**< Free all tagged contained widgets */ - gfxw_unary_container_op *free_contents; /**< Free all contained widgets */ - gfxw_rect_op *add_dirty_abs; /**< Add an absolute dirty rectangle */ - gfxw_rect_op *add_dirty_rel; /**< Add a relative dirty rectangle */ - gfxw_container_op *add; /**< Append widget to an appropriate position (for view and control lists) */ - -public: - // FIXME: This should be a virtual base class, mark it so somehow? - GfxContainer(rect_t area, gfxw_widget_type_t type); - ~GfxContainer(); - - virtual void tag(); - virtual void print(int indentation) const; - virtual int setVisual(GfxVisual *); -}; - - -#define GFXW_IS_CONTAINER(widget) ((widget)->_type == GFXW_PORT || (widget)->_type == GFXW_VISUAL || \ - (widget)->_type == GFXW_SORTED_LIST || (widget)->_type == GFXW_LIST) - -#define GFXW_IS_LIST(widget) ((widget)->_type == GFXW_LIST || (widget)->_type == GFXW_SORTED_LIST) -#define GFXW_IS_SORTED_LIST(widget) ((widget)->_type == GFXW_SORTED_LIST) -/** SCI graphics list */ -struct GfxList : public GfxContainer { -public: - GfxList(rect_t area, bool sorted); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -#define GFXW_IS_VISUAL(widget) ((widget)->_type == GFXW_VISUAL) -/** SCI graphic visual */ -struct GfxVisual : public GfxContainer { - Common::Array<GfxPort *> _portRefs; /**< References to ports */ - int _font; /**< Default font */ - GfxState *_gfxState; - -public: - GfxVisual(GfxState *state, int font); - ~GfxVisual(); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; - virtual int setVisual(GfxVisual *); - - GfxPort *getPort(int portId) { - return (portId < 0 || portId >= (int)_portRefs.size()) ? NULL : _portRefs[portId]; - } -}; - -#define GFXW_IS_PORT(widget) ((widget)->_type == GFXW_PORT) -/** SCI graphics port */ -struct GfxPort : public GfxContainer { - GfxList *_decorations; /**< optional window decorations - drawn before the contents */ - GfxWidget *port_bg; /**< Port background widget or NULL */ - gfx_color_t _color, _bgcolor; - int _font; - Common::Point draw_pos; /**< Drawing position */ - gfxw_snapshot_t *restore_snap; /**< Snapshot to be restored automagically, - experimental feature used in the PQ3 interpreter */ - int port_flags; /**< interpreter-dependant flags */ - Common::String _title_text; - byte gray_text; /**< Whether text is 'grayed out' (dithered) */ - -public: - /** - * Creates a new port widget with the default settings - * - * A port differentiates itself from a list in that it contains additional - * information, and an optional title (stored in a display list). - * Ports are assigned implicit IDs identifying their position within the - * port stack. - * - * @param[in] visual The visual the port is added to - * @param[in] area The screen area covered by the port (absolute - * position) - * @param[in] fgcolor Foreground drawing color - * @param[in] bgcolor Background color - */ - GfxPort(GfxVisual *visual, rect_t area, gfx_color_t fgcolor, gfx_color_t bgcolor); - ~GfxPort(); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; - virtual int setVisual(GfxVisual *); -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_STATE_INTERNAL_H - -#endif diff --git a/engines/sci/gfx/gfx_support.cpp b/engines/sci/gfx/gfx_support.cpp deleted file mode 100644 index 8efe59b855..0000000000 --- a/engines/sci/gfx/gfx_support.cpp +++ /dev/null @@ -1,281 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -/* Graphics support functions for drivers and replacements for driver functions -** for use with the graphical state manager -*/ - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_tools.h" - -#include "common/endian.h" -#include "graphics/primitives.h" - -namespace Sci { - -#define LINEMACRO(startx, starty, deltalinear, deltanonlinear, linearvar, nonlinearvar, \ - linearend, nonlinearstart, linearmod, nonlinearmod) \ - incrNE = ((deltalinear) > 0) ? (deltalinear) : -(deltalinear); \ - incrNE <<= 1; \ - deltanonlinear <<= 1; \ - incrE = ((deltanonlinear) > 0) ? -(deltanonlinear) : (deltanonlinear); \ - d = nonlinearstart - 1; \ - while (linearvar != (linearend)) { \ - memcpy(buffer + linewidth * (starty) + (startx), &color, pixelwidth); \ - linearvar += linearmod; \ - if ((d += incrE) < 0) { \ - d += incrNE; \ - nonlinearvar += nonlinearmod; \ - }; \ - }; \ - memcpy(buffer + linewidth * (starty) + (startx), &color, pixelwidth); - - -// Sierra's Bresenham line drawing -// WARNING: Do not just blindly replace this with Graphics::drawLine(), as it seems to create issues with flood fill -void gfx_draw_line_buffer(byte *buffer, int linewidth, int pixelwidth, Common::Point start, Common::Point end, unsigned int color) { - int incrE, incrNE, d; - int dx = ABS(end.x - start.x); - int dy = ABS(end.y - start.y); -#ifdef SCUMM_BIG_ENDIAN - color = SWAP_BYTES_32(color); -#endif - - if (dx > dy) { - int sign1 = (end.x < start.x) ? -1 : 1; - int sign2 = (end.y < start.y) ? -1 : 1; - LINEMACRO(start.x, start.y, dx, dy, start.x, start.y, end.x, dx, sign1 * pixelwidth, sign2); - } else { // dx <= dy - int sign1 = (end.y < start.y) ? -1 : 1; - int sign2 = (end.x < start.x) ? -1 : 1; - LINEMACRO(start.x, start.y, dy, dx, start.y, start.x, end.y, dy, sign1, sign2 * pixelwidth); - } - } - -#undef LINEMACRO - -void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, Common::Point end, int color) { - gfx_draw_line_buffer(pxm->index_data, pxm->index_width, 1, start, end, color); -} - -void gfx_draw_box_buffer(byte *buffer, int linewidth, rect_t zone, int color) { - byte *dest = buffer + zone.x + (linewidth * zone.y); - int i; - - if (zone.width <= 0 || zone.height <= 0) - return; - - for (i = 0; i < zone.height; i++) { - memset(dest, color, zone.width); - dest += linewidth; - } -} - -void gfx_draw_box_pixmap_i(gfx_pixmap_t *pxm, rect_t box, int color) { - gfx_clip_box_basic(&box, pxm->index_width - 1, pxm->index_height - 1); - - gfx_draw_box_buffer(pxm->index_data, pxm->index_width, box, color); -} - - -void _gfx_crossblit(byte *dest, byte *src, int bytes_per_dest_line, int bytes_per_src_line, - int xl, int yl, byte *alpha, int bytes_per_alpha_line, int bytes_per_alpha_pixel, - unsigned int alpha_test_mask, unsigned int alpha_min, - byte *priority_buffer, int bytes_per_priority_line, int bytes_per_priority_pixel, int priority, - bool usePriority) { - int x, y; - int alpha_end = xl * bytes_per_alpha_pixel; - - for (y = 0; y < yl; y++) { - int pixel_offset = 0; - int alpha_offset = 0; - int priority_offset = 0; - - for (x = 0; x < alpha_end; x += bytes_per_alpha_pixel) { - if (((alpha_test_mask & alpha[x]) < alpha_min) ^ 1) { - - if (usePriority) { - if (priority_buffer[priority_offset] <= priority) { - priority_buffer[priority_offset] = priority; - memcpy(dest + pixel_offset, src + pixel_offset, 1); - } - } else { - memcpy(dest + pixel_offset, src + pixel_offset, 1); - } - } - - pixel_offset++; - alpha_offset += bytes_per_alpha_pixel; - if (usePriority) - priority_offset += bytes_per_priority_pixel; - } - - dest += bytes_per_dest_line; - src += bytes_per_src_line; - alpha += bytes_per_alpha_line; - if (usePriority) - priority_buffer += bytes_per_priority_line; - } -} - -void _gfx_crossblit_simple(byte *dest, byte *src, int dest_line_width, int src_line_width, int xl, int yl) { - int line_width = xl; - int i; - - for (i = 0; i < yl; i++) { - memcpy(dest, src, line_width); - dest += dest_line_width; - src += src_line_width; - } -} - -void gfx_crossblit_pixmap(gfx_mode_t *mode, gfx_pixmap_t *pxm, int priority, rect_t src_coords, rect_t dest_coords, - byte *dest, int dest_line_width, byte *priority_dest, int priority_line_width, int priority_skip) { - int maxx = 320 * mode->scaleFactor; - int maxy = 200 * mode->scaleFactor; - byte *src = pxm->data; - byte *alpha = pxm->alpha_map ? pxm->alpha_map : pxm->data; - byte *priority_pos = priority_dest; - unsigned int alpha_mask, alpha_min; - int xl = pxm->width, yl = pxm->height; - int xoffset = (dest_coords.x < 0) ? - dest_coords.x : 0; - int yoffset = (dest_coords.y < 0) ? - dest_coords.y : 0; - - if (src_coords.x + src_coords.width > xl) - src_coords.width = xl - src_coords.x; - - if (src_coords.y + src_coords.height > yl) - src_coords.height = yl - src_coords.y; - - // --???-- - if (src_coords.y > yl) - return; - if (src_coords.x > xl) - return; - // --???-- - - if (dest_coords.x + xl >= maxx) - xl = maxx - dest_coords.x; - if (dest_coords.y + yl >= maxy) - yl = maxy - dest_coords.y; - - xl -= xoffset; - yl -= yoffset; - - if (!pxm->data) - error("Attempted to crossblit an empty pixmap"); - - if (xl <= 0 || yl <= 0) - return; - - // Set destination offsets - - // Set x offsets - dest += dest_coords.x; - priority_pos += dest_coords.x * priority_skip; - - // Set y offsets - dest += dest_coords.y * dest_line_width; - priority_pos += dest_coords.y * priority_line_width; - - // Set source offsets - if (xoffset += src_coords.x) { - dest_coords.x = 0; - src += xoffset; - alpha += xoffset; - } - - - if (yoffset += src_coords.y) { - dest_coords.y = 0; - src += yoffset * pxm->width; - alpha += yoffset * pxm->width; - } - - // Adjust length for clip box - if (xl > src_coords.width) - xl = src_coords.width; - if (yl > src_coords.height) - yl = src_coords.height; - - // now calculate alpha - if (pxm->alpha_map) - alpha_mask = 0xff; - else { - int shift_nr = 0; - - alpha_mask = 0; - if (!alpha_mask && pxm->alpha_map) - error("Invalid alpha mode: both pxm->alpha_map and alpha_mask are white"); - - if (alpha_mask) { - while (!(alpha_mask & 0xff)) { - alpha_mask >>= 8; - shift_nr++; - } - alpha_mask &= 0xff; - } - -#ifdef SCUMM_BIG_ENDIAN - alpha += 1 - (shift_nr + 1); -#else - alpha += shift_nr; -#endif - } - - /** - * Crossblitting functions use this value as threshold for distinguishing - * between transparent and opaque wrt alpha values. - */ - int gfx_crossblit_alpha_threshold = 0x90; // was 128 - - if (alpha_mask & 0xff) - alpha_min = ((alpha_mask * gfx_crossblit_alpha_threshold) >> 8) & alpha_mask; - else - alpha_min = ((alpha_mask >> 8) * gfx_crossblit_alpha_threshold) & alpha_mask; - - alpha_min = 255 - alpha_min; // Since we use it for the reverse effect - - if (!alpha_mask) - _gfx_crossblit_simple(dest, src, dest_line_width, pxm->width, xl, yl); - else - - if (priority == GFX_NO_PRIORITY) { - _gfx_crossblit(dest, src, dest_line_width, pxm->width, - xl, yl, alpha, pxm->width, 1, alpha_mask, alpha_min, - 0, 0, 0, 0, false); - } else { // priority - _gfx_crossblit(dest, src, dest_line_width, pxm->width, - xl, yl, alpha, pxm->width, 1, alpha_mask, alpha_min, - priority_pos, priority_line_width, priority_skip, priority, true); - } -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_system.h b/engines/sci/gfx/gfx_system.h deleted file mode 100644 index d57c68552e..0000000000 --- a/engines/sci/gfx/gfx_system.h +++ /dev/null @@ -1,286 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_SYSTEM -#define SCI_GFX_GFX_SYSTEM - -#include "common/scummsys.h" -#include "common/rect.h" -#include "sci/gfx/palette.h" - -namespace Sci { - -#define GFX_DEBUG - -/***********************/ -/*** Data structures ***/ -/***********************/ - -#define GFX_MODE_IS_UNSCALED(mode) (((mode)->scaleFactor == 1) && ((mode)->scaleFactor == 1)) - -/** Graphics mode description - * - * Color masks: - * Each of the mask/shift pairs describe where the corresponding color - * values are stored for the described mode. Internally, color - * calculations are done by using 32 bit values for r, g, b, a. After - * the internal values have been calculated, they are shifted RIGHT - * by the xxx_shift amount described above, then ANDed with the - * corresponding color mask; finally, all three results are ORred to- - * gether. The alpha values are used as appropriate; if alpha_mask is - * zero, then images use a special alpha map. - */ - -struct gfx_mode_t { - - int scaleFactor; /**< Horizontal and vertical scaling factor */ - int xsize, ysize; /**< Horizontal and vertical size */ - - /** - * Palette or NULL to indicate non-palette mode. - */ - Palette *palette; -}; - - -// TODO: Replace rect_t by Common::Rect -/** Rectangle description */ -struct rect_t { - int x, y; - int width, height; /* width, height: (x,y,width,height)=(5,5,1,1) occupies 1 pixel */ -}; - -/** - * Generates a rect_t from index data - * - * @param[in] x Left side of the rectangle - * @param[in] y Top side of the rectangle - * @param[in] width Horizontal extent of the rectangle - * @param[in] height Verical extent of the rectangle - * @return A rectangle matching the supplied parameters - */ -static inline rect_t gfx_rect(int x, int y, int width, int height) { - rect_t rect; - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - - return rect; -} - -/** - * Temporary helper function to ease the transition from rect_t to Common::Rect - */ -static inline rect_t toSCIRect(Common::Rect in) { - return gfx_rect(in.left, in.top, in.width(), in.height()); -} - -/** - * Temporary helper function to ease the transition from rect_t to Common::Rect - */ -static inline Common::Rect toCommonRect(rect_t in) { - return Common::Rect(in.x, in.y, in.x + in.width, in.y + in.height); -} - -#define GFX_PRINT_RECT(rect) (rect).x, (rect).y, (rect).width, (rect).height - -#define OVERLAP(a, b, z, zl) (a.z >= b.z && a.z < (b.z + b.zl)) - -/** - * Determines whether two rects overlap - * - * @param[in] a First rect to check for overlap - * @param[in] b Second rect to check for overlap - * @return 1 if they overlap, 0 otherwise - */ -static inline int gfx_rects_overlap(rect_t a, rect_t b) { - return (OVERLAP(a, b, x, width) || OVERLAP(b, a, x, width)) && (OVERLAP(a, b, y, height) || OVERLAP(b, a, y, height)); -} - -#undef OVERLAP - -/* gfx_rect_fullscreen is declared in gfx/gfx_tools.c */ -extern rect_t gfx_rect_fullscreen; - -#define GFX_RESID_NONE -1 - -#define GFX_PIC_COLORS 256 - -#define GFX_PIXMAP_COLOR_KEY_NONE -1 /* No transpacency colour key */ -#define GFX_CURSOR_TRANSPARENT 255 // Cursor colour key - -/** Pixel map */ -struct gfx_pixmap_t { - - /** @name Meta information - * @{*/ - int ID; /**< Resource ID, or GFX_RESID_NONE for anonymous graphical data */ - short loop; /**< loop number for view */ - short cel; /**< cel number for view */ - /** @}*/ - - /** @name Color map - * @{*/ - Palette *palette; - - /** - * color entries, or NULL if the default palette is to be used. A maximum - * of 255 colors is allowed; color index 0xff is reserved for transparency. - * As a special exception, 256 colors are allowed for background pictures - * (which do not use transparency) - */ - int colors_nr() const { return palette ? MIN<int>(palette->size(), 256) : 0; } - - uint32 flags; - /* @} */ - - /** @name Hot spot - * x and y coordinates of the 'hot spot' (unscaled) - * @{*/ - int xoffset, yoffset; - /** @} */ - - /** @name Index data - * @{ - */ - int index_width; /**< width of the indexed original image */ - int index_height; /**< height of the indexed original image */ - byte *index_data; /**< Color-index data, or NULL if read from an external source */ - /** @} */ - - /** @name Drawable data - * @{ - */ - int width; /**< width of the actual image */ - int height; /**< height of the actual image */ - int data_size; /**< Amount of allocated memory */ - byte *data; /**< Drawable data, or NULL if not converted. */ - - byte *alpha_map; /**< Byte map with alpha values. It is used only if the graphics mode's alpha_mask is zero. */ - - int color_key; /**< The color to make transparent */ - int palette_revision; /**< Revision of palette at the time data was generated */ - /** @} */ -}; - - - - -/** @name Constant values - * @{ */ - -/** Map masks */ -enum gfx_map_mask_t { - GFX_MASK_NONE = 0, - GFX_MASK_VISUAL = 1, - GFX_MASK_PRIORITY = 2, - GFX_MASK_CONTROL = 4 -}; - -/** 'no priority' mode */ -enum { - GFX_NO_PRIORITY = -1 -}; - -/** Text alignment values */ -enum gfx_alignment_t { - ALIGN_RIGHT = -1, - ALIGN_TOP = -1, - ALIGN_CENTER = 1, - ALIGN_LEFT = 0, - ALIGN_BOTTOM = 0 -}; - - -enum gfx_line_mode_t { - GFX_LINE_MODE_CORRECT, /**< Scaled separately */ - GFX_LINE_MODE_FAST, /**< Scaled by (xfact+yfact)/2 */ - GFX_LINE_MODE_FINE /**< Always drawn at width 1 */ -}; - -enum gfx_brush_mode_t { - GFX_BRUSH_MODE_SCALED, /**< Just scale the brush pixels */ - GFX_BRUSH_MODE_ELLIPSES, /**< Replace pixels with ellipses */ - GFX_BRUSH_MODE_RANDOM_ELLIPSES, /**< Replace pixels with ellipses moved and re-scaled randomly */ - GFX_BRUSH_MODE_MORERANDOM /**< Distribute randomly */ -}; - - -enum gfx_line_style_t { - GFX_LINE_STYLE_NORMAL, - GFX_LINE_STYLE_STIPPLED -}; - - -enum gfx_rectangle_fill_t { - GFX_SHADE_FLAT, /**< Don't shade */ - GFX_SHADE_VERTICALLY, /**< Shade vertically */ - GFX_SHADE_HORIZONTALLY /**< Shade horizontally */ -}; - -/** @} */ - -/** Full color */ -struct gfx_color_t { - PaletteEntry visual; - uint8 alpha; /**< transparency = (1-opacity) */ - int8 priority, control; - byte mask; /**< see mask values below */ - - bool operator==(const gfx_color_t &c) const { - if (mask != c.mask) - return false; - - if (mask & GFX_MASK_VISUAL) { - if (visual.r != c.visual.r || visual.g != c.visual.g || visual.b != c.visual.b || alpha != c.alpha) - return false; - } - - if (mask & GFX_MASK_PRIORITY) - if (priority != c.priority) - return false; - - if (mask & GFX_MASK_CONTROL) - if (control != c.control) - return false; - - return true; - } - - bool operator!=(const gfx_color_t &c) const { - return !(*this == c); - } -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_SYSTEM - -#endif diff --git a/engines/sci/gfx/gfx_tools.cpp b/engines/sci/gfx/gfx_tools.cpp deleted file mode 100644 index 0ea488fe1d..0000000000 --- a/engines/sci/gfx/gfx_tools.cpp +++ /dev/null @@ -1,163 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - -rect_t gfx_rect_fullscreen = {0, 0, 320, 200}; - -void gfx_clip_box_basic(rect_t *box, int maxx, int maxy) { - if (box->x < 0) - box->x = 0; - - if (box->y < 0) - box->y = 0; - - if (box->x + box->width > maxx) - box->width = maxx - box->x + 1; - - if (box->y + box->height > maxy) - box->height = maxy - box->y + 1; -} - -gfx_mode_t *gfx_new_mode(int scaleFactor, Palette *palette) { - gfx_mode_t *mode = (gfx_mode_t *)malloc(sizeof(gfx_mode_t)); - - mode->scaleFactor = scaleFactor; - mode->xsize = scaleFactor * 320; - mode->ysize = scaleFactor * 200; - mode->palette = palette; - - return mode; -} - -void gfx_free_mode(gfx_mode_t *mode) { - mode->palette->free(); - free(mode); - mode = NULL; -} - -void gfx_copy_pixmap_box_i(gfx_pixmap_t *dest, gfx_pixmap_t *src, rect_t box) { - int width, height; - int offset; - - if ((dest->index_width != src->index_width) || (dest->index_height != src->index_height)) - return; - - gfx_clip_box_basic(&box, dest->index_width, dest->index_height); - - if (box.width <= 0 || box.height <= 0) - return; - - height = box.height; - width = box.width; - - offset = box.x + (box.y * dest->index_width); - - while (height--) { - memcpy(dest->index_data + offset, src->index_data + offset, width); - offset += dest->index_width; - } -} - -gfx_pixmap_t *gfx_new_pixmap(int xl, int yl, int resid, int loop, int cel) { - gfx_pixmap_t *pxm = (gfx_pixmap_t *)malloc(sizeof(gfx_pixmap_t)); - - pxm->alpha_map = NULL; - pxm->data = NULL; - pxm->palette = NULL; - pxm->palette_revision = -1; - - pxm->index_width = xl; - pxm->index_height = yl; - - pxm->ID = resid; - pxm->loop = loop; - pxm->cel = cel; - - pxm->index_data = NULL; - - pxm->flags = 0; - - pxm->color_key = 0xff; - - return pxm; -} - -void gfx_free_pixmap(gfx_pixmap_t *pxm) { - if (pxm->palette) - pxm->palette->free(); - - free(pxm->index_data); - free(pxm->alpha_map); - free(pxm->data); - free(pxm); -} - -gfx_pixmap_t *gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap) { - int size; - - if (pixmap->index_data) { - warning("[GFX] Attempt to allocate pixmap index data twice"); - return pixmap; - } - - size = pixmap->index_width * pixmap->index_height; - if (!size) - size = 1; - - pixmap->index_data = (byte*)malloc(size); - - memset(pixmap->index_data, 0, size); - - return pixmap; -} - -gfx_pixmap_t *gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode) { - int size; - - if (pixmap->data) { - warning("[GFX] Attempt to allocate pixmap data twice"); - return pixmap; - } - - pixmap->width = pixmap->index_width; - pixmap->height = pixmap->index_height; - - size = pixmap->width * pixmap->height; - if (!size) - size = 1; - - pixmap->data = (byte*)malloc(pixmap->data_size = size); - return pixmap; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_tools.h b/engines/sci/gfx/gfx_tools.h deleted file mode 100644 index 06543532e8..0000000000 --- a/engines/sci/gfx/gfx_tools.h +++ /dev/null @@ -1,191 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_TOOLS_H -#define SCI_GFX_GFX_TOOLS_H - -#include "graphics/pixelformat.h" - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_driver.h" - -namespace Sci { - -/** @name SCI graphics subsystem helper functions */ -/** @{ */ - -/** - * Allocates a new gfx_mode_t structure with the specified parameters - * - * @param[in] xfact Horizontal scaling factors - * @param[in] yfact Vertical scaling factors - * @param[in] palette Number of palette colors, 0 if we're not in palette mode - * @return A newly allocated gfx_mode_t structure - */ -gfx_mode_t *gfx_new_mode(int scaleFactor, Palette *palette); - -/** - * Clips a rect_t - * - * @param[in] box Pointer to the box to clip - * @param[in] maxx Maximum allowed width - * @param[in] maxy Maximum allowed height - */ -void gfx_clip_box_basic(rect_t *box, int maxx, int maxy); - -/** - * Frees all memory allocated by a mode structure - * @param[in] mode The mode to free - */ -void gfx_free_mode(gfx_mode_t *mode); - -/** - * Creates a new pixmap structure - * - * The following fiels are initialized: - * ID, loop, cel, index_width, index_height, xl, yl, data <- NULL, - * alpha_map <- NULL, internal.handle <- 0, internal.info <- NULL, - * colors <- NULL, index_scaled <- 0 - * - * @param[in] xl Width (in SCI coordinates) of the pixmap - * @param[in] yl Height (in SCI coordinates) of the pixmap - * @param[in] resid The pixmap's resource ID, or GFX_RESID_NONE - * @param[in] loop For views: The pixmap's loop number - * @param[in] cel For cels: The pixmap's cel number - * @return The newly allocated pixmap - */ -gfx_pixmap_t *gfx_new_pixmap(int xl, int yl, int resid, int loop, int cel); - -/** - * Allocates the index_data field of a pixmap - * - * @param[in] pixmap The pixmap to allocate for - * @return The pixmap - */ -gfx_pixmap_t *gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap); - -/** - * Allocates the data field of a pixmap - * - * @param[in] pixmap The pixmap to allocate for - * @param[in] mode The mode the memory is to be allocated for - * @return The pixmap - */ -gfx_pixmap_t *gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode); - -/** - * Frees all memory associated with a pixmap - * - * @param[in] pxm The pixmap to free - */ -void gfx_free_pixmap(gfx_pixmap_t *pxm); - -/** - * Draws a line to a pixmap's index data buffer - * - * Remember, this only draws to the /index/ buffer, not to the drawable buffer. - * The line is not clipped. Invalid x, y, x1, y1 values will result in memory - * corruption. - * - * @param[in] pxm The pixmap to draw to - * @param[in] start Starting point of the line to draw - * @param[in] end End point of the line to draw - * @param[in] color The byte value to write - */ -void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, - Common::Point end, int color); - -void gfx_draw_line_buffer(byte *buffer, int linewidth, int pixelwidth, - Common::Point start, Common::Point end, unsigned int color); - -/** - * Draws a filled rectangular area to a pixmap's index buffer - * - * This function only draws to the index buffer. - * - * @param[in] pxm The pixmap to draw to - * @param[in] box The box to fill - * @param[in] color The color to use for drawing - */ -void gfx_draw_box_pixmap_i(gfx_pixmap_t *pxm, rect_t box, int color); - -void gfx_draw_box_buffer(byte *buffer, int linewidth, rect_t zone, int color); - -/** - * Copies part of a pixmap to another pixmap, with clipping - * - * @param[in] dest The destination pixmap - * @param[in] src The source pixmap - * @param[in] box The area to copy - */ -void gfx_copy_pixmap_box_i(gfx_pixmap_t *dest, gfx_pixmap_t *src, rect_t box); - -/** - * Translates a pixmap's index data to drawable graphics data - * - * @param[in] pxm The pixmap to translate - * @param[in] mode The mode according which to scale - */ -void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode); - -/** - * Transfers the non-transparent part of a pixmap to a linear pixel - * buffer. - * - * A 'linear buffer' in this context means a data buffer containing an entire - * screen (visual or priority), with fixed offsets between each data row, and - * linear access. - * - * @param[in] mode The graphics mode of the target buffer - * @param[in] pxm The pixmap to transfer - * @param[in] priority The pixmap's priority - * @param[in] src_coords The source coordinates within the pixmap - * @param[in] dest_coords The destination coordinates (no scaling) - * @param[in] dest Memory position of the upper left pixel of - * the linear pixel buffer - * @param[in] dest_line_width Byte offset of the very first pixel in the - * second line of the linear pixel buffer, - * relative to dest. - * @param[in] priority_dest Destination buffer for the pixmap's priority - * values - * @param[in] priority_line_width Byte offset of the first pixel in the second - * line of the priority buffer - * @param[in] priority_skip Amount of bytes allocated by each priority - * value - */ -void gfx_crossblit_pixmap(gfx_mode_t *mode, gfx_pixmap_t *pxm, int priority, - rect_t src_coords, rect_t dest_coords, byte *dest, int dest_line_width, - byte *priority_dest, int priority_line_width, int priority_skip); - - -/** @} */ -} // End of namespace Sci - -#endif // SCI_GFX_GFX_TOOLS_H - -#endif diff --git a/engines/sci/gfx/gfx_widgets.cpp b/engines/sci/gfx/gfx_widgets.cpp deleted file mode 100644 index d260e66cfc..0000000000 --- a/engines/sci/gfx/gfx_widgets.cpp +++ /dev/null @@ -1,1775 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/gfx_gui.h" // for kWindowAutoRestore -#include "sci/gfx/gfx_widgets.h" -#include "sci/gfx/gfx_state_internal.h" - -namespace Sci { - -#undef GFXW_DEBUG_DIRTY // Enable to debug dirty rectangle propagation (writes to stderr) - -#ifdef GFXW_DEBUG_DIRTY -# define DDIRTY fprintf(stderr, "%s:%5d| ", __FILE__, __LINE__); fprintf -#else -# define DDIRTY if (0) fprintf -#endif - -Common::Point gfxw_point_zero(0, 0); - -#define MAX_SERIAL_NUMBER 0x7fffffff -static int widget_serial_number_counter = 0x10000; // Avoid confusion with IDs - -#ifdef GFXW_DEBUG_WIDGETS - -GfxWidget *debug_widgets[GFXW_DEBUG_WIDGETS]; -int debug_widget_pos = 0; - -static void _gfxw_debug_add_widget(GfxWidget *widget) { - if (debug_widget_pos == GFXW_DEBUG_WIDGETS) - error("WIDGET DEBUG: Allocated the maximum number of %d widgets- Aborting!\n", GFXW_DEBUG_WIDGETS); - debug_widgets[debug_widget_pos++] = widget; -} - -static void _gfxw_debug_remove_widget(GfxWidget *widget) { - int i; - int found = 0; - for (i = 0; i < debug_widget_pos; i++) { - if (debug_widgets[i] == widget) { - memmove(debug_widgets + i, debug_widgets + i + 1, (sizeof(GfxWidget *)) * (debug_widget_pos - i - 1)); - debug_widgets[debug_widget_pos--] = NULL; - found++; - } - } - - if (found > 1) { - error("While removing widget: Found it %d times!\n", found); - } - - if (found == 0) { - error("Attempted removal of unregistered widget!\n"); - } -} -#else // !GFXW_DEBUG_WIDGETS -#define _gfxw_debug_add_widget(a) -#define _gfxw_debug_remove_widget(a) -#endif - - -static void indent(int indentation) { - for (int i = 0; i < indentation; i++) - printf(" "); -} - -void GfxWidget::printIntern(int indentation) const { - unsigned int i; - char flags_list[] = "VOCDTMI"; - - indent(indentation); - - if (_magic == GFXW_MAGIC_VALID) { - if (_visual) - printf("v "); - else - printf("NoVis "); - } else if (_magic == GFXW_MAGIC_INVALID) - printf("INVALID "); - - printf("S%08x", _serial); - - if (_ID != GFXW_NO_ID) { - printf("#%x", _ID); - - if (_subID != GFXW_NO_ID) - printf(":%x ", _subID); - else - printf(" "); - } - - printf("[(%d,%d)(%dx%d)]", _bounds.x, _bounds.y, _bounds.width, _bounds.height); - - for (i = 0; i < strlen(flags_list); i++) - if (_flags & (1 << i)) - printf("%c", flags_list[i]); - - printf(" "); -} - -void GfxWidget::print(int indentation) const { - printIntern(indentation); - printf("<untyped #%d>", _type); -} - -GfxWidget::GfxWidget(gfxw_widget_type_t type_) { - _magic = GFXW_MAGIC_VALID; - - _serial = widget_serial_number_counter++; - widget_serial_number_counter &= MAX_SERIAL_NUMBER; - - _flags = GFXW_FLAG_DIRTY; - _type = type_; - _bounds = gfx_rect(0, 0, 0, 0); - _next = NULL; - _ID = GFXW_NO_ID; - _subID = GFXW_NO_ID; - _parent = NULL; - _visual = NULL; - _widgetPriority = -1; - - compare_to = NULL; - equals = NULL; - should_replace = NULL; - superarea_of = NULL; - - _gfxw_debug_add_widget(this); -} - -static int verify_widget(GfxWidget *widget) { - if (!widget) { - warning("Attempt to use NULL widget"); - return 1; - } else if (widget->_magic != GFXW_MAGIC_VALID) { - if (widget->_magic == GFXW_MAGIC_INVALID) { - warning("Attempt to use invalidated widget"); - } else { - warning("Attempt to use non-widget"); - } - return 1; - } - return 0; -} - -#define VERIFY_WIDGET(w) \ - if (verify_widget((GfxWidget *)(w))) { error("Error occured while validating widget"); } - -//********** Widgets ************* - -// Base class operations and common stuff - -// Assertion for drawing -#define DRAW_ASSERT(widget, exp_type) \ - if (!(widget)) { \ - printf("L%d: NULL widget", __LINE__); \ - return 1; \ - } \ - if ((widget)->_type != (exp_type)) { \ - printf("L%d: Error in widget: Expected type " # exp_type "(%d) but got %d\n", __LINE__, exp_type, (widget)->_type); \ - printf("Erroneous widget: "); \ - widget->print(4); \ - printf("\n"); \ - return 1; \ - } \ - if (!(widget->_flags & GFXW_FLAG_VISIBLE)) \ - return 0; \ - if (!(widget->_type == GFXW_VISUAL || widget->_visual)) { \ - printf("L%d: Error while drawing widget: Widget has no visual\n", __LINE__); \ - printf("Erroneous widget: "); \ - widget->print(1); \ - printf("\n"); \ - return 1; \ - } - -int GfxWidget::setVisual(GfxVisual *visual) { - _visual = visual; - - if (_parent) { - DDIRTY(stderr, "GfxWidget::setVisual: DOWNWARDS rel(%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(_bounds)); - _parent->add_dirty_rel(_parent, _bounds, 1); - } - - return 0; -} - -static int _gfxwop_basic_should_replace(GfxWidget *widget, GfxWidget *other) { - return 0; -} - -static void _gfxw_set_ops(GfxWidget *widget, - gfxw_bin_op *compare_to, gfxw_bin_op *equals, gfxw_bin_op *superarea_of) { - widget->compare_to = compare_to; - widget->equals = equals; - widget->superarea_of = superarea_of; - - widget->should_replace = _gfxwop_basic_should_replace; -} - -void gfxw_remove_widget_from_container(GfxContainer *container, GfxWidget *widget) { - GfxWidget **seekerp; - - if (!container) { - error("Attempt to remove widget from NULL container!\n"); - } - - seekerp = &(container->_contents); - - if (GFXW_IS_LIST(widget) && GFXW_IS_PORT(container)) { - GfxPort *port = (GfxPort *) container; - if (port->_decorations == (GfxList *) widget) { - port->_decorations = NULL; - return; - } - } - - while (*seekerp && *seekerp != widget) - seekerp = &((*seekerp)->_next); - - if (!*seekerp) { - printf("Internal error: Attempt to remove widget from container it was not contained in!\n"); - printf("Widget:"); - widget->print(1); - printf("Container:"); - widget->print(1); - error("gfxw_remove_widget_from_container() failed. Breakpoint in %s, line %d", __FILE__, __LINE__); - return; - } - - if (container->_nextpp == &(widget->_next)) - container->_nextpp = seekerp; - - *seekerp = widget->_next; // Remove it - widget->_parent = NULL; - widget->_next = NULL; -} - -GfxWidget::~GfxWidget() { - DDIRTY(stderr, "BASIC-FREE: SomeAddDirty\n"); // FIXME: What is this? - - if (_parent) { - if (GFXW_IS_CONTAINER(this)) - _parent->add_dirty_abs(_parent, _bounds, 1); - else - _parent->add_dirty_rel(_parent, _bounds, 1); - - gfxw_remove_widget_from_container(_parent, this); - } - - _magic = GFXW_MAGIC_INVALID; - _gfxw_debug_remove_widget(this); -} - -static int _gfxwop_basic_compare_to(GfxWidget *widget, GfxWidget *other) { - return 1; -} - -static int _gfxwop_basic_equals(GfxWidget *widget, GfxWidget *other) { - return 0; -} - -static int _gfxwop_basic_superarea_of(GfxWidget *widget, GfxWidget *other) { - return (widget == other); -} - -//*** Boxes *** - -static rect_t _move_rect(rect_t rect, Common::Point point) { - return gfx_rect(rect.x + point.x, rect.y + point.y, rect.width, rect.height); -} - -static void _split_rect(rect_t rect, Common::Point *p1, Common::Point *p2) { - p1->x = rect.x; - p1->y = rect.y; - p2->x = rect.x + rect.width; - p2->y = rect.y + rect.height; -} - -static Common::Point _move_point(rect_t rect, Common::Point point) { - return Common::Point(rect.x + point.x, rect.y + point.y); -} - -int GfxBox::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_BOX); - gfxop_draw_box(_visual->_gfxState, _move_rect(_bounds, pos), _color1, _color2, _shadeType); - return 0; -} - -void GfxBox::print(int indentation) const { - printIntern(indentation); - printf("BOX"); -} - -static int _gfxwop_box_superarea_of(GfxWidget *widget, GfxWidget *other) { - GfxBox *box = (GfxBox *) widget; - - if (box->_color1.alpha) - return 0; - - if (box->_shadeType != GFX_BOX_SHADE_FLAT && box->_color2.alpha) - return 0; - - // Note: the check for box->_bounds and other->_bounds is NOT the same as contains() - // in Common::Rect (this one includes equality too) - if (!(box->_bounds.x <= other->_bounds.x && box->_bounds.y <= other->_bounds.y && - box->_bounds.x + box->_bounds.width >= other->_bounds.x + other->_bounds.width && - box->_bounds.y + box->_bounds.height >= other->_bounds.y + other->_bounds.height)) - return 0; - - return 1; -} - -static int _gfxwop_box_equals(GfxWidget *widget, GfxWidget *other) { - GfxBox *wbox = (GfxBox *)widget, *obox; - if (other->_type != GFXW_BOX) - return 0; - - obox = (GfxBox *) other; - - if (!toCommonRect(wbox->_bounds).equals(toCommonRect(obox->_bounds))) - return 0; - - if (wbox->_color1 != obox->_color1) - return 0; - - if (wbox->_shadeType != obox->_shadeType) - return 0; - - if (wbox->_shadeType != GFX_BOX_SHADE_FLAT - && wbox->_color2 == obox->_color2) - return 0; - - return 1; -} - -void _gfxw_set_ops_BOX(GfxWidget *widget) { - _gfxw_set_ops(widget, _gfxwop_basic_compare_to, _gfxwop_box_equals, _gfxwop_box_superarea_of); -} - -static int _gfxw_color_get_priority(gfx_color_t color) { - return (color.mask & GFX_MASK_PRIORITY) ? color.priority : -1; -} - -GfxBox *gfxw_new_box(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) { - return new GfxBox(state, area, color1, color2, shade_type); -} - -GfxBox::GfxBox(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) - : GfxWidget(GFXW_BOX) { - - _widgetPriority = _gfxw_color_get_priority(color1); - _bounds = area; - _color1 = color1; - _color2 = color2; - _shadeType = shade_type; - - _flags |= GFXW_FLAG_VISIBLE; - - if ((_color1.mask & GFX_MASK_VISUAL) && ((state && (state->driver->getMode()->palette)) || (!_color1.alpha && !_color2.alpha))) - _flags |= GFXW_FLAG_OPAQUE; - - _gfxw_set_ops_BOX(this); -} - -GfxPrimitive::GfxPrimitive(rect_t area, gfx_color_t color_, gfx_line_mode_t mode, - gfx_line_style_t style, gfxw_widget_type_t type_) - : GfxWidget(type_) { - - _widgetPriority = _gfxw_color_get_priority(color_); - _bounds = area; - _color = color_; - _lineMode = mode; - _lineStyle = style; - - _flags |= GFXW_FLAG_VISIBLE; -} - -//*** Rectangles *** - -struct GfxRect : public GfxPrimitive { - GfxRect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -static int _gfxwop_primitive_equals(GfxWidget *widget, GfxWidget *other) { - GfxPrimitive *wprim = (GfxPrimitive *) widget, *oprim; - if (widget->_type != other->_type) - return 0; - - oprim = (GfxPrimitive *) other; - - // Check if the two primitives are equal (note: the primitives aren't always rectangles, so - // the "width" and the "height" here could be negative) - if (wprim->_bounds.x != oprim->_bounds.x || wprim->_bounds.y != oprim->_bounds.y || - wprim->_bounds.width != oprim->_bounds.width || wprim->_bounds.height != oprim->_bounds.height) - return 0; - - if (wprim->_color != oprim->_color) - return 0; - - if (wprim->_lineMode != oprim->_lineMode) - return 0; - - if (wprim->_lineStyle != oprim->_lineStyle) - return 0; - - return 1; -} - -int GfxRect::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_RECT); - - gfxop_draw_rectangle(_visual->_gfxState, gfx_rect(_bounds.x + pos.x, _bounds.y + pos.y, - _bounds.width - 1, _bounds.height - 1), _color, _lineMode, _lineStyle); - return 0; -} - -void GfxRect::print(int indentation) const { - printIntern(indentation); - printf("RECT"); -} - -void _gfxw_set_ops_RECT(GfxWidget *prim) { - _gfxw_set_ops(prim, - _gfxwop_basic_compare_to, _gfxwop_primitive_equals, _gfxwop_basic_superarea_of); -} - -GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style) { - return new GfxRect(rect, color, line_mode, line_style); -} - -GfxRect::GfxRect(rect_t rect, gfx_color_t color_, gfx_line_mode_t line_mode_, gfx_line_style_t line_style_) - : GfxPrimitive(rect, color_, line_mode_, line_style_, GFXW_RECT) { - - _bounds.width++; - _bounds.height++; // Since it is actually one pixel bigger in each direction - - _gfxw_set_ops_RECT(this); -} - -//*** Lines *** - -struct GfxLine : public GfxPrimitive { - GfxLine(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -int GfxLine::draw(const Common::Point &pos) { - rect_t linepos = _bounds; - Common::Point p1, p2; - - linepos.width--; - linepos.height--; - - DRAW_ASSERT(this, GFXW_LINE); - - _split_rect(_move_rect(linepos, pos), &p1, &p2); - gfxop_draw_line(_visual->_gfxState, p1, p2, _color, _lineMode, _lineStyle); - return 0; -} - -void GfxLine::print(int indentation) const { - printIntern(indentation); -// printf("LINE"); -} - -void _gfxw_set_ops_LINE(GfxWidget *prim) { - _gfxw_set_ops(prim, - _gfxwop_basic_compare_to, _gfxwop_primitive_equals, _gfxwop_basic_superarea_of); -} - -GfxPrimitive *gfxw_new_line(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style) { - return new GfxLine(start, end, color, line_mode, line_style); -} - -GfxLine::GfxLine(Common::Point start, Common::Point end, gfx_color_t color_, gfx_line_mode_t line_mode_, gfx_line_style_t line_style_) - : GfxPrimitive(gfx_rect(start.x, start.y, end.x - start.x + 1, end.y - start.y + 1), color_, line_mode_, line_style_, GFXW_LINE) { - _gfxw_set_ops_LINE(this); -} - -//*** Views and static views *** - - -GfxView::GfxView(GfxState *state, Common::Point pos_, int view_, int loop_, int cel_, int palette_, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int flags_) - : GfxWidget((flags_ & GFXW_VIEW_FLAG_STATIC) ? GFXW_STATIC_VIEW : GFXW_VIEW) { - - int width, height; - Common::Point offset; - - if (!state) { - error("Attempt to create view widget with NULL state"); - } - - gfxop_get_cel_parameters(state, view_, loop_, cel_, &width, &height, &offset); - - _pos = pos_; - _color.mask = ((priority < 0) ? 0 : GFX_MASK_PRIORITY) | ((control < 0) ? 0 : GFX_MASK_CONTROL); - _widgetPriority = priority; - _color.priority = priority; - _color.control = control; - _view = view_; - _loop = loop_; - _cel = cel_; - _palette = palette_; - - if (halign == ALIGN_CENTER) - _pos.x -= width >> 1; - else if (halign == ALIGN_RIGHT) - _pos.x -= width; - - if (valign == ALIGN_CENTER) - _pos.y -= height >> 1; - else if (valign == ALIGN_BOTTOM) - _pos.y -= height; - - _bounds = gfx_rect(_pos.x - offset.x, _pos.y - offset.y, width, height); - - _flags |= GFXW_FLAG_VISIBLE; -} - -int GfxView::draw(const Common::Point &pos) { - if (_type == GFXW_VIEW) { - DRAW_ASSERT(this, GFXW_VIEW); - gfxop_draw_cel(_visual->_gfxState, _view, _loop, _cel, - Common::Point(_pos.x + pos.x, _pos.y + pos.y), _color, _palette); - } else { - // FIXME: _gfxwop_static_view_draw checked for GFXW_VIEW here, instead of GFXW_STATIC_VIEW. - //DRAW_ASSERT(this, GFXW_VIEW); - DRAW_ASSERT(this, GFXW_STATIC_VIEW); - gfxop_draw_cel_static(_visual->_gfxState, _view, _loop, _cel, - _move_point(_bounds, pos), _color, _palette); - } - return 0; -} - -void GfxView::print(int indentation) const { - printIntern(indentation); - - if (_type == GFXW_STATIC_VIEW) - printf("STATICVIEW"); - else if (_type == GFXW_VIEW) - printf("VIEW"); - else - error("GfxView::print: Invalid type %d", _type); - - printf("(%d/%d/%d)@(%d,%d)[p:%d,c:%d]", _view, _loop, _cel, _pos.x, _pos.y, - (_color.mask & GFX_MASK_PRIORITY) ? _color.priority : -1, - (_color.mask & GFX_MASK_CONTROL) ? _color.control : -1); -} - -void _gfxw_set_ops_VIEW(GfxWidget *view, char stat) { - _gfxw_set_ops(view, _gfxwop_basic_compare_to, _gfxwop_basic_equals, _gfxwop_basic_superarea_of); -} - -GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view_nr, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int flags) { - GfxView *view; - - if (flags & GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET) { - int foo; - Common::Point offset; - gfxop_get_cel_parameters(state, view_nr, loop, cel, &foo, &foo, &offset); - pos.x += offset.x; - pos.y += offset.y; - } - - view = new GfxView(state, pos, view_nr, loop, cel, palette, priority, control, halign, valign, - (flags & GFXW_VIEW_FLAG_STATIC) ? GFXW_STATIC_VIEW : GFXW_VIEW); - - _gfxw_set_ops_VIEW(view, (char)(flags & GFXW_VIEW_FLAG_STATIC)); - - return view; -} - -//*** Dynamic Views *** - -int GfxDynView::draw(const Common::Point &pos) { - if (_type == GFXW_DYN_VIEW) { - DRAW_ASSERT(this, GFXW_DYN_VIEW); - - gfxop_draw_cel(_visual->_gfxState, _view, _loop, _cel, - _move_point(draw_bounds, pos), _color, _palette); - - /* - gfx_color_t red; - red.visual.r = 0xff; - red.visual.g = red.visual.b = 0; - red.mask = GFX_MASK_VISUAL; - gfxop_draw_rectangle(view->visual->_gfxState, - gfx_rect(view->_bounds.x + pos.x, view->_bounds.y + pos.y, view->_bounds.width - 1, view->_bounds.height - 1), red, 0, 0); - */ - } else { - DRAW_ASSERT(this, GFXW_PIC_VIEW); - - if (_isDrawn) - return 0; - - gfxop_set_clip_zone(_visual->_gfxState, _parent->zone); - gfxop_draw_cel_static_clipped(_visual->_gfxState, _view, _loop, - _cel, _move_point(draw_bounds, pos), _color, _palette); - - // Draw again on the back buffer - gfxop_draw_cel(_visual->_gfxState, _view, _loop, _cel, - _move_point(draw_bounds, pos), _color, _palette); - - - _isDrawn = true; // No more drawing needs to be done - } - - return 0; -} - - void GfxDynView::print(int indentation) const { - printIntern(indentation); - - if (_type == GFXW_DYN_VIEW) - printf("DYNVIEW"); - else if (_type == GFXW_PIC_VIEW) - printf("PICVIEW"); - else - error("GfxDynView::print: Invalid type %d", _type); - - printf(" SORT=%d z=%d seq=%d (%d/%d/%d)@(%d,%d)[p:%d,c:%d]; sig[%04x@%04X:%04X[%d]]", force_precedence, _z, - sequence, _view, _loop, _cel, _pos.x, _pos.y, - (_color.mask & GFX_MASK_PRIORITY) ? _color.priority : -1, - (_color.mask & GFX_MASK_CONTROL) ? _color.control : -1, signal, signalp.obj.segment, signalp.obj.offset, signalp.varindex); -} - -static int _gfxwop_dyn_view_equals(GfxWidget *widget, GfxWidget *other) { - GfxDynView *wview = (GfxDynView *)widget, *oview; - if (!GFXW_IS_DYN_VIEW(other)) - return 0; - - oview = (GfxDynView *)other; - - if (wview->_pos.x != oview->_pos.x || wview->_pos.y != oview->_pos.y || wview->_z != oview->_z) - return 0; - - if (wview->_view != oview->_view || wview->_loop != oview->_loop || wview->_cel != oview->_cel) - return 0; - - if (wview->_color != oview->_color) - return 0; - - if (wview->_flags != oview->_flags) - return 0; - - return 1; -} - -static int _gfxwop_dyn_view_compare_to(GfxWidget *widget, GfxWidget *other) { - int retval; - GfxDynView *wview = (GfxDynView *) widget, *oview; - if (!GFXW_IS_DYN_VIEW(other)) - return 1; - - oview = (GfxDynView *) other; - - retval = wview->force_precedence - oview->force_precedence; - if (retval) - return retval; - - retval = wview->_pos.y - oview->_pos.y; - if (retval) - return retval; - - retval = (wview->_z - oview->_z); - if (retval) - return retval; - - return -(wview->sequence - oview->sequence); -} - -void _gfxw_set_ops_DYNVIEW(GfxWidget *widget) { - _gfxw_set_ops(widget, _gfxwop_dyn_view_compare_to, _gfxwop_dyn_view_equals, _gfxwop_basic_superarea_of); -} - -void _gfxw_set_ops_PICVIEW(GfxWidget *widget) { - _gfxw_set_ops_DYNVIEW(widget); -} - -GfxDynView *gfxw_new_dyn_view(GfxState *state, Common::Point pos, int z, int view, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int sequence) { - - return new GfxDynView(state, pos, z, view, loop, cel, palette, priority, control, halign, valign, sequence); -} - -GfxDynView::GfxDynView(GfxState *state, Common::Point pos_, int z_, int view_, int loop_, int cel_, int palette_, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int sequence_) - : GfxView(state, pos_, view_, loop_, cel_, palette_, priority, control, halign, valign, 0) { - int width, height; - int xalignmod, yalignmod; - Common::Point offset; - - _type = GFXW_DYN_VIEW; - - if (!state) - error("Attempt to create view widget with NULL state"); - - gfxop_get_cel_parameters(state, view_, loop_, cel_, &width, &height, &offset); - - _pos = pos_; - _color.mask = ((priority < 0) ? 0 : GFX_MASK_PRIORITY) | ((control < 0) ? 0 : GFX_MASK_CONTROL); - _widgetPriority = priority; - _color.priority = priority; - _color.control = control; - _view = view_; - _loop = loop_; - _cel = cel_; - _palette = palette_; - - _color.alpha = 0; - _color.visual = PaletteEntry(0,0,0); // FIXME: black! - - if (halign == ALIGN_CENTER) - xalignmod = width >> 1; - else if (halign == ALIGN_RIGHT) - xalignmod = width; - else - xalignmod = 0; - - if (valign == ALIGN_CENTER) - yalignmod = height >> 1; - else if (valign == ALIGN_BOTTOM) - yalignmod = height; - else - yalignmod = 0; - - draw_bounds = gfx_rect(_pos.x - xalignmod, _pos.y - yalignmod - z_, width, height); - _bounds = gfx_rect(_pos.x - offset.x - xalignmod, _pos.y - offset.y - yalignmod - z_, width, height); - - under_bitsp.obj = NULL_REG; - under_bits = 0; - signalp.obj = NULL_REG; - signal = 0; - _z = z_; - sequence = sequence_; - force_precedence = 0; - - _isDrawn = false; - - _flags |= GFXW_FLAG_VISIBLE; - - _gfxw_set_ops_DYNVIEW(this); -} - -//*** Text *** - -GfxText::~GfxText() { - if (_textHandle) { - GfxState *state = _visual ? _visual->_gfxState : NULL; - if (!state) { - error("Attempt to free text without supplying mode to free it from!\n"); - } else { - delete _textHandle; - _textHandle = NULL; - } - } -} - -int GfxText::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_TEXT); - - if (_textHandle == 0) { - _textHandle = gfxop_new_text(_visual->_gfxState, _font, _text, _bounds.width, - halign, valign, _color1, _color2, _bgcolor, _textFlags); - } - - gfxop_draw_text(_visual->_gfxState, _textHandle, _move_rect(_bounds, pos)); - return 0; -} - -void GfxText::print(int indentation) const { - printIntern(indentation); - printf("TEXT:'%s'", _text.c_str()); -} - -static int _gfxwop_text_equals(GfxWidget *widget, GfxWidget *other) { - GfxText *wtext = (GfxText *)widget, *otext; - if (other->_type != GFXW_TEXT) - return 0; - - otext = (GfxText *)other; - - if ((wtext->_bounds.x != otext->_bounds.x) || (wtext->_bounds.y != otext->_bounds.y)) - return 0; - - if (wtext->halign != otext->halign || wtext->valign != otext->valign) - return 0; - - if (wtext->_textFlags != otext->_textFlags) - return 0; - - if (wtext->_font != otext->_font) - return 0; - - /* if (!(wtext->_color1 == otext->_color1 && wtext->_color2 == otext->_color2 - && wtext->_bgcolor == otext->_bgcolor)) - return 0; */ - - return 1; -} - -static int _gfxwop_text_should_replace(GfxWidget *widget, GfxWidget *other) { - GfxText *wtext = (GfxText *)widget, *otext; - - if (other->_type != GFXW_TEXT) - return 0; - - otext = (GfxText *)other; - - return wtext->_text != otext->_text; -} - -static int _gfxwop_text_compare_to(GfxWidget *widget, GfxWidget *other) { - return 1; -} - -void _gfxw_set_ops_TEXT(GfxWidget *widget) { - _gfxw_set_ops(widget, - _gfxwop_text_compare_to, _gfxwop_text_equals, - _gfxwop_basic_superarea_of); - widget->should_replace = _gfxwop_text_should_replace; -} - -GfxText *gfxw_new_text(GfxState *state, rect_t area, int font, const char *text, gfx_alignment_t halign, - gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, gfx_color_t bgcolor, int text_flags) { - return new GfxText(state, area, font, text, halign, valign, color1, color2, bgcolor, text_flags); -} - -GfxText::GfxText(GfxState *state, rect_t area, int font, const char *text, gfx_alignment_t halign_, - gfx_alignment_t valign_, gfx_color_t color1_, gfx_color_t color2_, gfx_color_t bgcolor_, int text_flags_) - : GfxWidget(GFXW_TEXT) { - - _widgetPriority = _gfxw_color_get_priority(color1_); - _font = font; - _text = text; - halign = halign_; - valign = valign_; - _color1 = color1_; - _color2 = color2_; - _bgcolor = bgcolor_; - _textFlags = text_flags_; - _textHandle = NULL; - - gfxop_get_text_params(state, font, text, area.width, &width, &height, _textFlags, - &lines_nr, &lineheight, &lastline_width); - - /* FIXME: Window is too big - area.x += _calc_needmove(halign, area.width, width); - area.y += _calc_needmove(valign, area.height, height); - */ - - if (halign == ALIGN_LEFT) - area.width = width; - if (valign == ALIGN_TOP) - area.height = height; - - _bounds = area; - - _flags |= GFXW_FLAG_VISIBLE; - - _gfxw_set_ops_TEXT(this); -} - -void gfxw_text_info(GfxState *state, GfxText *text, int *lines, int *lineheight, int *offset) { - if (lines) - *lines = text->lines_nr; - if (lineheight) - *lineheight = text->lineheight; - if (offset) - *offset = text->lastline_width; -} - -//-- Container types -- - -static int _gfxwop_container_add_dirty_rel(GfxContainer *cont, rect_t rect, int propagate) { - DDIRTY(stderr, "->container_add_dirty_rel(%d,%d,%d,%d, %d)\n", GFX_PRINT_RECT(rect), propagate); - return cont->add_dirty_abs(cont, _move_rect(rect, Common::Point(cont->zone.x, cont->zone.y)), propagate); -} - -static void _gfxw_set_container_ops(GfxContainer *container, - gfxw_bin_op *compare_to, gfxw_bin_op *equals, - gfxw_bin_op *superarea_of, - gfxw_unary_container_op *free_tagged, gfxw_unary_container_op *free_contents, - gfxw_rect_op *add_dirty, gfxw_container_op *add) { - _gfxw_set_ops(container, compare_to, equals, superarea_of); - - container->free_tagged = free_tagged; - container->free_contents = free_contents; - container->add_dirty_abs = add_dirty; - container->add_dirty_rel = _gfxwop_container_add_dirty_rel; - container->add = add; -} - -static int _w_gfxwop_container_print_contents(const char *name, GfxWidget *widget, int indentation) { - GfxWidget *seeker = widget; - - indent(indentation); - - printf("--%s:\n", name); - - while (seeker) { - seeker->print(indentation + 1); - printf("\n"); - seeker = seeker->_next; - } - - return 0; -} - -void GfxContainer::print(int indentation) const { - printf(" viszone=((%d,%d),(%dx%d))\n", zone.x, zone.y, zone.width, zone.height); - - indent(indentation); - printf("--dirty:\n"); - - for (DirtyRectList::const_iterator dirty = _dirtyRects.begin(); dirty != _dirtyRects.end(); ++dirty) { - indent(indentation + 1); - printf("dirty(%d,%d, (%dx%d))\n", dirty->x, dirty->y, dirty->width, dirty->height); - } - - _w_gfxwop_container_print_contents("contents", _contents, indentation); -} - - -GfxContainer::GfxContainer(rect_t area, gfxw_widget_type_t type_) - : GfxWidget(type_) { - _bounds = zone = area; - _contents = NULL; - _nextpp = &_contents; - - free_tagged = NULL; - free_contents = NULL; - add_dirty_abs = NULL; - add_dirty_rel = NULL; - add = NULL; - - _flags |= GFXW_FLAG_VISIBLE | GFXW_FLAG_CONTAINER; -} - -static int _gfxw_dirty_rect_overlaps_normal_rect(rect_t port_zone, rect_t bounds, rect_t dirty) { - bounds.x += port_zone.x; - bounds.y += port_zone.y; - - return gfx_rects_overlap(bounds, dirty); -} - -static int _gfxwop_container_draw_contents(GfxWidget *widget, GfxWidget *contents) { - GfxContainer *container = (GfxContainer *)widget; - GfxState *gfx_state = (widget->_visual) ? widget->_visual->_gfxState : ((GfxVisual *) widget)->_gfxState; - int draw_ports; - rect_t nullzone = {0, 0, 0, 0}; - - if (!contents) - return 0; - - DirtyRectList::iterator dirty = container->_dirtyRects.begin(); - while (dirty != container->_dirtyRects.end()) { - GfxWidget *seeker = contents; - - while (seeker) { - if (_gfxw_dirty_rect_overlaps_normal_rect(GFXW_IS_CONTAINER(seeker) ? nullzone : container->zone, - // Containers have absolute coordinates, reflect this. - seeker->_bounds, *dirty)) { - - if (GFXW_IS_CONTAINER(seeker)) {// Propagate dirty rectangles /upwards/ - DDIRTY(stderr, "container_draw_contents: propagate upwards (%d,%d,%d,%d ,0)\n", GFX_PRINT_RECT(*dirty)); - ((GfxContainer *)seeker)->add_dirty_abs((GfxContainer *)seeker, *dirty, 0); - } - - seeker->_flags |= GFXW_FLAG_DIRTY; - } - - seeker = seeker->_next; - } - - ++dirty; - } - - // The draw loop is executed twice: Once for normal data, and once for ports. - for (draw_ports = 0; draw_ports < 2; draw_ports++) { - - dirty = container->_dirtyRects.begin(); - while (dirty != container->_dirtyRects.end()) { - GfxWidget *seeker = contents; - // FIXME: Ugly hack to check whether this is the last dirty rect or not - DirtyRectList::iterator next = dirty; - ++next; - const bool isLastDirtyRect = (next == container->_dirtyRects.end()); - - while (seeker && (draw_ports || !GFXW_IS_PORT(seeker))) { - rect_t small_rect = *dirty; - bool draw_noncontainers = !_gfxop_clip(&small_rect, container->_bounds); - - if (seeker->_flags & GFXW_FLAG_DIRTY) { - - if (!GFXW_IS_CONTAINER(seeker) && draw_noncontainers) { - gfxop_set_clip_zone(gfx_state, small_rect); - } - /* Clip zone must be reset after each element, because we might - ** descend into containers. - ** Doing this is relatively cheap, though. */ - if (draw_noncontainers || GFXW_IS_CONTAINER(seeker)) - seeker->draw(Common::Point(container->zone.x, container->zone.y)); - - if (isLastDirtyRect) - seeker->_flags &= ~GFXW_FLAG_DIRTY; - } - - seeker = seeker->_next; - } - ++dirty; - } - } - // Remember that the dirty rects should be freed afterwards! - - return 0; -} - -GfxContainer::~GfxContainer() { - GfxWidget *seeker = _contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - delete seeker; - seeker = next; - } - - _dirtyRects.clear(); -} - -void GfxContainer::tag() { - // FIXME: Should we also tag this object itself? - GfxWidget *seeker = _contents; - while (seeker) { - seeker->tag(); - seeker = seeker->_next; - } -} - -int GfxContainer::setVisual(GfxVisual *visual) { - _visual = visual; - if (_parent) { - if (!(GFXW_IS_LIST(this) && !_contents)) { - DDIRTY(stderr, "set_visual::DOWNWARDS abs(%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(_bounds)); - _parent->add_dirty_abs(_parent, _bounds, 1); - } - } - - GfxWidget *seeker = _contents; - while (seeker) { - seeker->setVisual(visual); - seeker = seeker->_next; - } - return 0; -} - -static int _gfxwop_container_free_tagged(GfxContainer *container) { - GfxWidget *seeker = container->_contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - if (seeker->_flags & GFXW_FLAG_TAGGED) - delete seeker; - seeker = next; - } - - return 0; -} - -static int _gfxwop_container_free_contents(GfxContainer *container) { - GfxWidget *seeker = container->_contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - delete seeker; - seeker = next; - } - return 0; -} - -static void _gfxw_dirtify_container(GfxContainer *container, GfxWidget *widget) { - if (GFXW_IS_CONTAINER(widget)) - container->add_dirty_abs(container, widget->_bounds, 1); - else - container->add_dirty_rel(container, widget->_bounds, 1); -} - -static int _parentize_widget(GfxContainer *container, GfxWidget *widget) { - if (widget->_parent) { - printf("_parentize_widget(): Attempt to give second parent node to widget!\nWidget:"); - widget->print(3); - printf("\nContainer:"); - container->print(3); - error("Error in _parentize_widget()"); - return 1; - } - - widget->_parent = container; - - if (GFXW_IS_VISUAL(container)) - widget->setVisual((GfxVisual *)container); - else if (container->_visual) - widget->setVisual(container->_visual); - - return 0; -} - -static int _gfxw_container_id_equals(GfxContainer *container, GfxWidget *widget) { - GfxWidget **seekerp = &(container->_contents); - - if (GFXW_IS_PORT(widget)) - return 0; - - if (widget->_ID == GFXW_NO_ID) - return 0; - - while (*seekerp && ((*seekerp)->_ID != widget->_ID || (*seekerp)->_subID != widget->_subID)) - seekerp = &((*seekerp)->_next); - - if (!*seekerp) - return 0; - - if ((*seekerp)->equals(*seekerp, widget) && !(*seekerp)->should_replace(*seekerp, widget)) { - delete widget; - (*seekerp)->_flags &= ~GFXW_FLAG_TAGGED; - return 1; - } else { - if (!(widget->_flags & GFXW_FLAG_MULTI_ID)) - delete *seekerp; - return 0; - } -} - -static int _gfxwop_container_add_dirty(GfxContainer *container, rect_t dirty, int propagate) { -#if 0 - // This code has been disabled because containers may contain sub-containers with - // bounds greater than their own. - if (_gfxop_clip(&dirty, container->_bounds)) - return 0; -#endif - - DDIRTY(stderr, "Effectively adding dirty %d,%d,%d,%d %d to ID %d\n", GFX_PRINT_RECT(dirty), propagate, container->_ID); - gfxdr_add_dirty(container->_dirtyRects, dirty); - return 0; -} - -static int _gfxwop_container_add(GfxContainer *container, GfxWidget *widget) { - if (_gfxw_container_id_equals(container, widget)) - return 0; - - if (_parentize_widget(container, widget)) - return 1; - - if (!(GFXW_IS_LIST(widget) && (!((GfxContainer *)widget)->_contents))) { // Don't dirtify self on empty lists - DDIRTY(stderr, "container_add: dirtify DOWNWARDS (%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(widget->_bounds)); - _gfxw_dirtify_container(container, widget); - } - - *(container->_nextpp) = widget; - container->_nextpp = &(widget->_next); - - return 0; -} - -//*** Lists and sorted lists *** - -int GfxList::draw(const Common::Point &pos) { - if (_type == GFXW_LIST) { - DRAW_ASSERT(this, GFXW_LIST); - - _gfxwop_container_draw_contents(this, _contents); - _flags &= ~GFXW_FLAG_DIRTY; - } else { - DRAW_ASSERT(this, GFXW_SORTED_LIST); - - _gfxwop_container_draw_contents(this, _contents); - } - _dirtyRects.clear(); - - return 0; -} - - -void GfxList::print(int indentation) const { - printIntern(indentation); - - if (_type == GFXW_LIST) - printf("LIST"); - else if (_type == GFXW_SORTED_LIST) - printf("SORTED_LIST"); - else - error("GfxList::print: Invalid type %d", _type); - - GfxContainer::print(indentation); -} - -static int _gfxwop_list_equals(GfxWidget *widget, GfxWidget *other) { - // Requires identical order of list elements. - GfxList *wlist, *olist; - - if (widget->_type != other->_type) - return 0; - - if (!GFXW_IS_LIST(widget)) { - warning("[GFX] _gfxwop_list_equals(): Method called on non-list"); - widget->print(0); - printf("\n"); - return 0; - } - - wlist = (GfxList *)widget; - olist = (GfxList *)other; - - if (memcmp(&(wlist->_bounds), &(olist->_bounds), sizeof(rect_t))) - return 0; - - widget = wlist->_contents; - other = olist->_contents; - - while (widget && other) { - if (!(widget->equals(widget, other) && !widget->should_replace(widget, other))) - return 0; - - widget = widget->_next; - other = other->_next; - } - - return (!widget && !other); // True if both are finished now -} - -static int _gfxwop_list_add_dirty(GfxContainer *container, rect_t dirty, int propagate) { - // Lists add dirty boxes to both themselves and their parenting port/visual - - container->_flags |= GFXW_FLAG_DIRTY; - - DDIRTY(stderr, "list_add_dirty %d,%d,%d,%d %d\n", GFX_PRINT_RECT(dirty), propagate); - if (propagate) - if (container->_parent) { - DDIRTY(stderr, "->PROPAGATING\n"); - container->_parent->add_dirty_abs(container->_parent, dirty, 1); - } - - return _gfxwop_container_add_dirty(container, dirty, propagate); -} - -int _gfxwop_ordered_add(GfxContainer *container, GfxWidget *widget, int compare_all) { - // O(n) - GfxWidget **seekerp = &(container->_contents); - - if (widget->_next) { - printf("_gfxwop_ordered_add(): Attempt to add widget to two lists!\nWidget:"); - widget->print(3); - printf("\nList:"); - container->print(3); - error("Error in _gfxwop_ordered_add()"); - } - - if (_gfxw_container_id_equals(container, widget)) - return 0; - - while (*seekerp && (compare_all || (widget->compare_to(widget, *seekerp) >= 0))) { - - if (widget->equals(widget, *seekerp)) { - if (compare_all) { - if ((*seekerp)->_visual) - delete *seekerp; // If it's a fresh widget - else - gfxw_annihilate(*seekerp); - - return _gfxwop_ordered_add(container, widget, compare_all); // We might have destroyed the container's contents - } else { - widget->_next = (*seekerp)->_next; - delete *seekerp; - *seekerp = widget; - return (_parentize_widget(container, widget)); - } - } - - if (*seekerp) - seekerp = &((*seekerp)->_next); - } - - widget->_next = *seekerp; - *seekerp = widget; - - return _parentize_widget(container, widget); -} - -static int _gfxwop_sorted_list_add(GfxContainer *container, GfxWidget *widget) { - // O(n) - return _gfxwop_ordered_add(container, widget, 0); -} - -void _gfxw_set_ops_LIST(GfxContainer *list, char sorted) { - _gfxw_set_container_ops((GfxContainer *)list, - _gfxwop_basic_compare_to, sorted ? _gfxwop_basic_equals : _gfxwop_list_equals, - _gfxwop_basic_superarea_of, - _gfxwop_container_free_tagged, _gfxwop_container_free_contents, - _gfxwop_list_add_dirty, sorted ? _gfxwop_sorted_list_add : _gfxwop_container_add); -} - -GfxList *gfxw_new_list(rect_t area, int sorted) { - return new GfxList(area, sorted); -} - -GfxList::GfxList(rect_t area, bool sorted) - : GfxContainer(area, sorted ? GFXW_SORTED_LIST : GFXW_LIST) { - - _gfxw_set_ops_LIST(this, sorted); -} - - - -//*** Visuals *** - -int GfxVisual::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_VISUAL); - - for (DirtyRectList::iterator dirty = _dirtyRects.begin(); dirty != _dirtyRects.end(); ++dirty) { - gfxop_clear_box(_gfxState, *dirty); - } - - _gfxwop_container_draw_contents(this, _contents); - - _dirtyRects.clear(); - _flags &= ~GFXW_FLAG_DIRTY; - - return 0; -} - -void GfxVisual::print(int indentation) const { - printIntern(indentation); - printf("VISUAL; ports={"); - for (uint i = 0; i < _portRefs.size(); i++) { - if (_portRefs[i]) { - if (i != 0) - printf(","); - printf("%d", i); - } - } - printf("}\n"); - - GfxContainer::print(indentation); -} - -int GfxVisual::setVisual(GfxVisual *visual) { - if (this != visual) { - warning("Attempt to set a visual's parent visual to something else"); - } else { - warning("Attempt to set a visual's parent visual to itself"); - } - - return 1; -} - -void _gfxw_set_ops_VISUAL(GfxContainer *visual) { - _gfxw_set_container_ops((GfxContainer *)visual, - _gfxwop_basic_compare_to, - _gfxwop_basic_equals, _gfxwop_basic_superarea_of, - _gfxwop_container_free_tagged, _gfxwop_container_free_contents, - _gfxwop_container_add_dirty, _gfxwop_container_add); -} - -GfxVisual::GfxVisual(GfxState *state, int font) - : GfxContainer(gfx_rect(0, 0, 320, 200), GFXW_VISUAL) { - - _font = font; - _gfxState = state; - - _gfxw_set_ops_VISUAL(this); -} - -GfxVisual::~GfxVisual() { - // HACK: We must dispose all content *here* already, because our child widgets - // still may have references to this object, and will try to invoke methods - // of this object which try to access the already cleared _portRefs array - // when they are destroyed. - GfxWidget *seeker = _contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - delete seeker; - seeker = next; - } - _contents = 0; -} - -static int _visual_find_free_ID(GfxVisual *visual) { - uint id = 0; - - while (id < visual->_portRefs.size() && visual->_portRefs[id]) - id++; - - if (id == visual->_portRefs.size()) { // Out of ports? - visual->_portRefs.push_back(0); - } - - return id; -} - -//*** Ports *** - -int GfxPort::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_PORT); - - if (_decorations) { - DDIRTY(stderr, "Getting/applying deco dirty (multi)\n"); - - DDIRTY(stderr, "Adding multiple dirty to #%d\n", _decorations->_ID); - for (DirtyRectList::iterator dirty = _dirtyRects.begin(); dirty != _dirtyRects.end(); ++dirty) { - gfxdr_add_dirty(_decorations->_dirtyRects, *dirty); - } - - if (_decorations->draw(gfxw_point_zero)) { - _decorations->_dirtyRects.clear(); - return 1; // error - } - _decorations->_dirtyRects.clear(); - } - - _gfxwop_container_draw_contents(this, _contents); - - _dirtyRects.clear(); - _flags &= ~GFXW_FLAG_DIRTY; - - return 0; -} - -GfxPort::~GfxPort() { - if (_visual) { - if (_ID < 0 || _ID >= (int)_visual->_portRefs.size()) { - error("Attempt to free port #%d; allowed: [0..%d]", _ID, _visual->_portRefs.size()); - } - - if (_visual->_portRefs[_ID] != this) { - warning("[GFX] While freeing port %d: Port is at %p, but port list indicates %p", _ID, (void *)this, (void *)_visual->_portRefs[_ID]); - } else - _visual->_portRefs[_ID] = NULL; - - } - - delete _decorations; -} - -void GfxPort::print(int indentation) const { - printIntern(indentation); - printf("PORT"); - printf(" font=%d drawpos=(%d,%d)", _font, draw_pos.x, draw_pos.y); - if (gray_text) - printf(" (gray)"); - - GfxContainer::print(indentation); - _w_gfxwop_container_print_contents("decorations", _decorations, indentation); -} - -static int _gfxwop_port_superarea_of(GfxWidget *self, GfxWidget *other) { - GfxPort *port = (GfxPort *) self; - - if (!port->port_bg) - return _gfxwop_basic_superarea_of(self, other); - - return port->port_bg->superarea_of(port->port_bg, other); -} - -int GfxPort::setVisual(GfxVisual *visual) { - _visual = visual; - - if (_decorations) - if (_decorations->setVisual(visual)) { - warning("[GFX] Setting the visual for decorations failed for port "); - this->print(1); - return 1; - } - - return GfxContainer::setVisual(visual); -} - -static int _gfxwop_port_add_dirty(GfxContainer *widget, rect_t dirty, int propagate) { - GfxPort *self = (GfxPort *) widget; - - self->_flags |= GFXW_FLAG_DIRTY; - - _gfxwop_container_add_dirty(widget, dirty, propagate); - - DDIRTY(stderr, "Added dirty to ID %d\n", widget->_ID); - DDIRTY(stderr, "dirty= (%d,%d,%d,%d) bounds (%d,%d,%d,%d)\n", dirty.x, dirty.x, dirty.width, dirty.height, - widget->_bounds.x, widget->_bounds.y, widget->_bounds.width, widget->_bounds.height); -#if 0 - // FIXME: This is a worthwhile optimization - if (self->port_bg) { - GfxWidget foo; - - foo.bounds = dirty; // Yeah, sub-elegant, I know - foo.bounds.x -= self->zone.x; - foo.bounds.y -= self->zone.y; - if (self->port_bg->superarea_of(self->port_bg, &foo)) { - GfxContainer *parent = self->_parent; - while (parent) { - fprintf(stderr, "Dirtifying parent id %d\n", parent->_ID); - parent->_flags |= GFXW_FLAG_DIRTY; - parent = parent->_parent; - } - return 0; - } - } // else propagate to the parent, since we're not 'catching' the dirty rect -#endif - - if (propagate) - if (self->_parent) { - DDIRTY(stderr, "PROPAGATE\n"); - return self->_parent->add_dirty_abs(self->_parent, dirty, 1); - } - - return 0; -} - -static int _gfxwop_port_add(GfxContainer *container, GfxWidget *widget) { - // O(n) - return _gfxwop_ordered_add(container, widget, 1); -} - -void _gfxw_set_ops_PORT(GfxContainer *widget) { - _gfxw_set_container_ops((GfxContainer *)widget, - _gfxwop_basic_compare_to, _gfxwop_basic_equals, _gfxwop_port_superarea_of, - _gfxwop_container_free_tagged, _gfxwop_container_free_contents, - _gfxwop_port_add_dirty, _gfxwop_port_add); -} - -GfxPort::GfxPort(GfxVisual *visual_, rect_t area, gfx_color_t fgcolor, gfx_color_t bgcolor_) - : GfxContainer(area, GFXW_PORT) { - VERIFY_WIDGET(visual_); - - port_bg = NULL; - _parent = NULL; - _decorations = NULL; - draw_pos = Common::Point(0, 0); - gray_text = 0; - _color = fgcolor; - _bgcolor = bgcolor_; - _font = visual_->_font; - _ID = _visual_find_free_ID(visual_); - visual_->_portRefs[_ID] = this; - - _gfxw_set_ops_PORT(this); -} - -void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window, rect_t auto_rect) { - window->port_flags |= kWindowAutoRestore; - window->restore_snap = gfxw_make_snapshot(visual, auto_rect); -} - -GfxPort *gfxw_remove_port(GfxVisual *visual, GfxPort *port) { - GfxPort *parent; - VERIFY_WIDGET(visual); - VERIFY_WIDGET(port); - - if (!visual->_contents) { - warning("[GFX] Attempt to remove port from empty visual"); - return NULL; - } - - parent = (GfxPort *)port->_parent; - if (port->port_flags & kWindowAutoRestore) - gfxw_restore_snapshot(visual, port->restore_snap); - - delete port; - - while (parent && !GFXW_IS_PORT(parent)) - parent = (GfxPort *)parent->_parent; // Ascend through ancestors - - return parent; -} - -GfxPort *gfxw_find_default_port(GfxVisual *visual) { - int id = visual->_portRefs.size(); - - while (id--) { - GfxPort *port = visual->_portRefs[id]; - - if (port) - return port; - } - - return NULL; -} - -// - other functions - - -GfxWidget *gfxw_set_id(GfxWidget *widget, int ID, int subID) { - if (widget) { - widget->_ID = ID; - widget->_subID = subID; - } - - return widget; -} - -GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp) { - if (!widget) - return NULL; - - widget->under_bits = under_bits; - widget->under_bitsp = under_bitsp; - widget->signal = signal; - widget->signalp = signalp; - - return widget; -} - -GfxWidget *gfxw_remove_id(GfxContainer *container, int ID, int subID) { - GfxWidget **wp = &(container->_contents); - - while (*wp) { - if ((*wp)->_ID == ID && (subID == GFXW_NO_ID || (*wp)->_subID == subID)) { - GfxWidget *widget = *wp; - - *wp = (*wp)->_next; - widget->_next = NULL; - widget->_parent = NULL; - widget->_visual = NULL; - - return widget; - } - - wp = &((*wp)->_next); - } - - return NULL; -} - -GfxWidget *gfxw_hide_widget(GfxWidget *widget) { - if (widget->_flags & GFXW_FLAG_VISIBLE) { - widget->_flags &= ~GFXW_FLAG_VISIBLE; - - if (widget->_parent) - widget->_parent->add_dirty_rel(widget->_parent, widget->_bounds, 1); - } - - return widget; -} - -GfxWidget *gfxw_show_widget(GfxWidget *widget) { - if (!(widget->_flags & GFXW_FLAG_VISIBLE)) { - widget->_flags |= GFXW_FLAG_VISIBLE; - - if (widget->_parent) - widget->_parent->add_dirty_rel(widget->_parent, widget->_bounds, 1); - } - - return widget; -} - -gfxw_snapshot_t *gfxw_make_snapshot(GfxVisual *visual, rect_t area) { - gfxw_snapshot_t *retval = (gfxw_snapshot_t*)malloc(sizeof(gfxw_snapshot_t)); - - retval->serial = widget_serial_number_counter++; - - retval->area = area; - - // Work around subset semantics in gfx_rect_subset. - // This fixes the help icon in LSL5. */ - if (retval->area.width == 320) - retval->area.width = 321; - - return retval; -} - -int gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, GfxWidget *widget) { - int free_below = (snapshot->serial < widget_serial_number_counter) ? 0 : widget_serial_number_counter; - int free_above_eq = snapshot->serial; - rect_t bounds = widget->_bounds; - - if (!GFXW_IS_CONTAINER(widget) && widget->_parent) { - bounds.x += widget->_parent->_bounds.x; - bounds.y += widget->_parent->_bounds.y; - } - - // Note: the check for snapshot->area and bounds is NOT the same as contains() in Common::Rect - // (this one includes equality too) - return ((widget->_serial >= free_above_eq || widget->_serial < free_below) && - (snapshot->area.x <= bounds.x && snapshot->area.y <= bounds.y && - snapshot->area.x + snapshot->area.width >= bounds.x + bounds.width && - snapshot->area.y + snapshot->area.height >= bounds.y + bounds.height)); -} - -#define MAGIC_FREE_NUMBER -42 - -void _gfxw_free_contents_appropriately(GfxContainer *container, gfxw_snapshot_t *snapshot, int priority) { - GfxWidget *widget = container->_contents; - - while (widget) { - GfxWidget *next = widget->_next; - - if (gfxw_widget_matches_snapshot(snapshot, widget) && !(widget->_flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS) - && (priority == MAGIC_FREE_NUMBER || priority <= widget->_widgetPriority || widget->_widgetPriority == -1)) { - delete widget; - } else { - if (GFXW_IS_CONTAINER(widget)) - _gfxw_free_contents_appropriately((GfxContainer *)widget, snapshot, priority); - } - - widget = next; - } -} - -gfxw_snapshot_t *gfxw_restore_snapshot(GfxVisual *visual, gfxw_snapshot_t *snapshot) { - _gfxw_free_contents_appropriately((GfxContainer *)visual, snapshot, MAGIC_FREE_NUMBER); - - return snapshot; -} - -void gfxw_annihilate(GfxWidget *widget) { - GfxVisual *visual = widget->_visual; - int widget_priority = 0; - int free_overdrawn = 0; - - gfxw_snapshot_t snapshot; - if (!GFXW_IS_CONTAINER(widget) && widget->_parent && visual && (widget->_flags & GFXW_FLAG_VISIBLE)) { - snapshot.serial = 0; - snapshot.area = widget->_bounds; - snapshot.area.x += widget->_parent->zone.x; - snapshot.area.y += widget->_parent->zone.y; - free_overdrawn = 1; - widget_priority = widget->_widgetPriority; - } - - delete widget; - - if (free_overdrawn) - _gfxw_free_contents_appropriately((GfxContainer *)visual, &snapshot, widget_priority); -} - -GfxDynView *gfxw_picviewize_dynview(GfxDynView *dynview) { - dynview->_type = GFXW_PIC_VIEW; - dynview->_flags |= GFXW_FLAG_DIRTY; - - _gfxw_set_ops_PICVIEW(dynview); - - if (dynview->_parent) - _gfxw_dirtify_container(dynview->_parent, dynview); - - return dynview; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_widgets.h b/engines/sci/gfx/gfx_widgets.h deleted file mode 100644 index d30af8ce4e..0000000000 --- a/engines/sci/gfx/gfx_widgets.h +++ /dev/null @@ -1,477 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_WIDGETS_H -#define SCI_GFX_GFX_WIDGETS_H - -#include "common/rect.h" - -#include "sci/engine/vm.h" -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/operations.h" - -namespace Sci { -/** @name Widget Graphical State Management */ -/** @{ */ - -struct GfxState; -struct GfxBox; -struct GfxDynView; -struct GfxContainer; -struct GfxList; -struct GfxPort; -struct GfxPrimitive; -struct gfxw_snapshot_t; -struct GfxText; -struct GfxView; -struct GfxVisual; -struct GfxWidget; - - -/* Enable the next line to keep a list of pointers to all widgets, with up to the specified amount -** of members (/SLOW/) */ -//#define GFXW_DEBUG_WIDGETS 2048 - -/* Terminology -** -** Two special terms are used in here: /equivalent/ and /clear/. Their meanings -** in this context are as follows: -** -** /clear/: Clearing a widget means overwriting the space it occupies in the back -** buffer with data from the static buffer. This affects both the visual and the -** priority buffer, the static buffer (and any effect the widget may have had on -** it) is not touched. -** -** /equivalent/: Two Widgets A and B are equivalent if and only if either of the -** following conditions is met: -** a) Both A and B are text widgets, and they occupy the same bounding rectangle. -** b) Both A and B are dynview widgets, and they have the same unique ID -** Note that /equivalent/ is not really an equivalence relation- while it is ob- -** viously transitive and symmetrical, it is not reflexive (e.g. a box widget -** is not /equivalent/ to itself), although this might be a nice addition for the -** future. -*/ - - -/*********************************/ -/* Fundamental widget operations */ -/*********************************/ - - -/* gfxw_point_zero is declared in gfx/widgets.cpp */ -extern Common::Point gfxw_point_zero; - -/*********************/ -/* Widget operations */ -/*********************/ - -/* These are for documentation purposes only. The actual declarations are in -** gfx_state_internal.h. -** -** -** ************************** -** ** Container operations ** -** ************************** -** -** -** -- free_tagged(GfxContainer *self) -** Frees all tagged resources in the container -** Parameters: (GfxContainer *) self: self reference -** Returns : (int) 0 -** The container itself is never freed in this way. -** -** -** -- free_contents(GfxContainer *self) -** Frees all resources contained in the container -** Parameters: (GfxContainer *) self: self reference -** Returns : (int) 0 -** -** -** -- add_dirty_abs(GfxContainer *self, rect_t dirty, int propagate) -** Adds a dirty rectangle to the container's list of dirty rects -** Parameters: (GfxContainer *) self: self reference -** (rect_t) dirty: The rectangular screen area that is to be flagged -** as dirty, absolute to the screen -** (int) propagate: Whether the dirty rect should be propagated to the -** widget's parents -** Returns : (int) 0 -** Transparent containers will usually pass this value to their next ancestor, -** because areas below them might have to be redrawn. -** -** -** -- add_dirty_rel(GfxContainer *self, rect_t dirty, int propagate) -** Adds a dirty rectangle to the container's list of dirty rects -** Parameters: (GfxContainer *) self: self reference -** (rect_t) dirty: The rectangular screen area that is to be flagged -** as dirty, relative to the widget -** (int) propagate: Whether the dirty rect should be propagated to the -** widget's parents -** Returns : (int) 0 -** Transparent containers will usually pass this value to their next ancestor, -** because areas below them might have to be redrawn. -** -** -** -- add(GfxContainer *self, GfxWidget *widget) -** Adds a widget to the list of contained widgets -** Parameters: (GfxContainer *) self: self reference -** (GfxWidget *) widget: The widget to add -** Returns : (int) 0 -** Sorted lists sort their content into the list rather than adding it to the -** end. -*/ - - -/***************************/ -/* Basic widget generation */ -/***************************/ - -/*-- Primitive types --*/ - -/** - * Creates a new box - * - * The graphics state, if non-NULL, is used here for some optimizations. - * - * @param[in] state The (optional) state - * @param[in] area The box's dimensions, relative to its container - * widget - * @param[in] color1 The primary color - * @param[in] color2 The secondary color (ignored if shading is disabled) - * @param[in] shade_type The shade type for the box - * @return The resulting box widget - */ -GfxBox *gfxw_new_box(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type); - -/** - * Creates a new rectangle - * - * @param[in] rect The rectangle area - * @param[in] color The rectangle's color - * @param[in] line_mode The line mode for the lines that make up the - * rectangle - * @param[in] line_style The rectangle's lines' style - * @return The newly allocated rectangle widget (a Primitive) - */ -GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style); - -/** - * Creates a new line - * - * @param[in] start The line's origin - * @param[in] end The line's end point - * @param[in] color The line's color - * @param[in] line_mode The line mode to use for drawing - * @param[in] line_style The line style - * @return The newly allocated line widget (a Primitive) - */ -GfxPrimitive *gfxw_new_line(Common::Point start, Common::Point end, - gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); - -/** View flags */ -enum { - GFXW_VIEW_FLAG_STATIC = (1 << 0), /**< Whether the view should be static */ - GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET = (1 << 1) /**< Whether the view should _not_ apply its x/y offset modifyers */ -}; - -/** - * Creates a new view (a cel, actually) - * - * @param[in] state The graphics state - * @param[in] pos The position to place the view at - * @param[in] view The global cel ID - * @param[in] loop The global cel ID - * @param[in] cel The global cel ID - * @param[in] palette The palette to use - * @param[in] priority The priority to use for drawing, or -1 for none - * @param[in] control The value to write to the control map, or -1 for none - * @param[in] halign Horizontal cel alignment - * @param[in] valign Vertical cel alignment - * @param[in] flags Any combination of GFXW_VIEW_FLAGs - * @return A newly allocated cel according to the specs - */ -GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view, int loop, - int cel, int palette, int priority, int control, gfx_alignment_t halign, - gfx_alignment_t valign, int flags); - - -/** - * Creates a new dyn view - * - * Dynamic views are non-pic views with a unique global identifyer. This allows for drawing optimizations when they move or change shape. - * - * @param[in] state The graphics state - * @param[in] pos The position to place the dynamic view at - * @param[in] z The z coordinate - * @param[in] view The global cel ID - * @param[in] loop The global cel ID - * @param[in] cel The global cel ID - * @param[in] palette The palette to use - * @param[in] priority The priority to use for drawing, or -1 for none - * @param[in] control The value to write to the control map, or -1 for none - * @param[in] halign Horizontal cel alignment - * @param[in] valign Vertical cel alignment - * @param[in] sequence Sequence number: When sorting dynviews, this number is - * considered last for sorting (ascending order) - * @return A newly allocated cel according to the specs - */ -GfxDynView *gfxw_new_dyn_view(GfxState *state, Common::Point pos, int z, - int view, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int sequence); - -/** - * Creates a new text widget - * - * @param[in] state The state the text is to be calculated from - * @param[in] area The area the text is to be confined to (the yl value is - * only relevant for text aligment, though) - * @param[in] font The number of the font to use - * @param[in] text String to put in text widget - * @param[in] halign Horizontal text alignment - * @param[in] valign Vertical text alignment - * @param[in] color1 Text foreground colors (if not equal, the foreground is - * dithered between them) - * @param[in] color2 Text foreground colors (if not equal, the foreground is - * dithered between them) - * @param[in] bgcolor Text background color - * @param[in] flags GFXR_FONT_FLAGs, orred together (see gfx_resource.h) - * @return The resulting text widget - */ -GfxText *gfxw_new_text(GfxState *state, rect_t area, int font, const char *text, - gfx_alignment_t halign, gfx_alignment_t valign, gfx_color_t color1, - gfx_color_t color2, gfx_color_t bgcolor, int flags); - -/** - * Determines text widget meta-information - * - * @param[in] state The state to operate on - * @param[in] text The widget to query - * @param[out] lines_nr Number of lines used in the text - * @param[out] lineheight Pixel height (SCI scale) of each text line - * @param[out] offset Pixel offset (SCI scale) of the space after the last - * character in the last line - */ -void gfxw_text_info(GfxState *state, GfxText *text, int *lines_nr, - int *lineheight, int *offset); - -/** - * Sets a widget's ID - * - * A widget ID is unique within the container it is stored in, if and only if it - * was added to that container with gfxw_add(). This function handles widget == - * NULL gracefully (by doing nothing and returning NULL). - * - * @param[in] widget The widget whose ID should be set - * @param[in] ID The ID to set - * @param[in] subID The ID to set - * @return The widget - */ -GfxWidget *gfxw_set_id(GfxWidget *widget, int ID, int subID); - -/** - * Finds a widget with a specific ID in a container and removes it from there - * - * Search is non-recursive; widgets with IDs hidden in subcontainers will not - * be found. - * - * @param[in] container The container to search in - * @param[in] ID The ID to look for - * @param[in] subID The subID to look for, or GFXW_NO_ID for any - * @return The resulting widget or NULL if no match was found - */ -GfxWidget *gfxw_remove_id(GfxContainer *container, int ID, int subID); - -/** - * Initializes a dyn view's interpreter attributes - * - * @param[in] widget The widget affected - * @param[in] under_bits Interpreter-dependant data - * @param[in] under_bitsp Interpreter-dependant data - * @param[in] signal Interpreter-dependant data - * @param[in] signalp Interpreter-dependant data - * @return The widget - */ -GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, - const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp); - -/** - * Makes a widget invisible without removing it from the list of widgets - * - * Has no effect on invisible widgets - * - * @param[in] widget The widget to invisibilize - * @return The widget - */ -GfxWidget *gfxw_hide_widget(GfxWidget *widget); - -/** - * Makes an invisible widget reappear - * - * Does not affect visible widgets - * - * @param[in] widget The widget to show again - * @return The widget - */ -GfxWidget *gfxw_show_widget(GfxWidget *widget); - -/** - * Marks a widget as "abandoned" - * - * @param[in] widget The widget to abandon - * @return The widget - */ -GfxWidget *gfxw_abandon_widget(GfxWidget *widget); - -/** Container types */ -enum { - GFXW_LIST_UNSORTED = 0, - GFXW_LIST_SORTED = 1 -}; - -/** - * Creates a new list widget - * - * List widgets are also referred to as Display Lists. - * - * @param[in] area The area covered by the list (absolute position) - * @param[in] sorted Whether the list should be a sorted list - * @return A newly allocated list widget - */ -GfxList *gfxw_new_list(rect_t area, int sorted); - -/** - * Retrieves the default port from a visual - * - * The 'default port' is the last port to be instantiated; usually the topmost - * or highest-ranking port. - * - * @param[in] visual The visual the port should be retrieved from - * @return The default port, or NULL if no port is present - */ -GfxPort *gfxw_find_default_port(GfxVisual *visual); - -/** - * Sets rectangle to be restored upon port removal - * - * @param[in] visual The visual to operate on - * @param[in] window The affected window - * @param[in] auto_rect The area to restore - */ -void gfxw_port_set_auto_restore(GfxVisual *visual, GfxPort *window, rect_t auto_rect); - -/** - * Removes a port from a visual - * - * @param[in] visual The visual the port should be removed from - * @param[in] port The port to remove - * @return port's parent port, or NULL if it had none - */ -GfxPort *gfxw_remove_port(GfxVisual *visual, GfxPort *port); - -/** - * Removes the widget from the specified port - * - * @param[in] container The container it should be removed from - * @param[in] widget The widget to remove - */ -void gfxw_remove_widget_from_container(GfxContainer *container, GfxWidget *widget); - -/** - * Makes a "snapshot" of a visual - * - * It's not really a full qualified snaphot, though. See gfxw_restore_snapshot - * for a full discussion. This operation also increases the global serial number - * counter by one. - * - * @param[in] visual The visual a snapshot is to be taken of - * @param[in] area The area a snapshot should be taken of - * @return The resulting, newly allocated snapshot - */ -gfxw_snapshot_t *gfxw_make_snapshot(GfxVisual *visual, rect_t area); - -/** - * Predicate to test whether a widget would be destroyed by applying a snapshot - * - * @param[in] snapshot The snapshot to test against - * @param[in] widget The widget to test - * @return An appropriate boolean value - */ -int gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, GfxWidget *widget); - -/** - * Restores a snapshot to a visual - * - * The snapshot is not really restored; only more recent widgets touching - * the snapshotted area are destroyed. - * - * @param[in] visual The visual to operate on - * @param[in] snapshot The snapshot to restore - * @return The snapshot (still needs to be freed) - */ -gfxw_snapshot_t *gfxw_restore_snapshot(GfxVisual *visual, gfxw_snapshot_t *snapshot); - -/** - * As widget->widfree(widget), but destroys all overlapping widgets - * - * This operation calls widget->widfree(widget), but it also destroys all - * widgets with a higher or equal priority drawn after this widget. - * - * @param[in] widget The widget to use - */ -void gfxw_annihilate(GfxWidget *widget); - -/** - * Turns a dynview into a picview - * - * The only changes are in function and type variables, actually. - * - * @param[in] dynview The victim - * @return The victim, after his transformation - */ -GfxDynView *gfxw_picviewize_dynview(GfxDynView *dynview); - -/** - * Tags a window widget as automatically restoring the visual background - * upon removal. - * - * Also records the specified background rectangle, for later recovery. - * - * @param[in] visual The base visual - * @param[in] window The window to tag - * @param[in] auto_rect The background to remember - - */ -void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window, - rect_t auto_rect); - -/** @} */ -} // End of namespace Sci - -#endif // SCI_GFX_GFX_WIDGETS_H - -#endif diff --git a/engines/sci/gfx/menubar.cpp b/engines/sci/gfx/menubar.cpp deleted file mode 100644 index 8dcefdcd34..0000000000 --- a/engines/sci/gfx/menubar.cpp +++ /dev/null @@ -1,441 +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. - * - * $URL$ - * $Id$ - * - */ - -/* Management and drawing operations for the SCI0 menu bar */ -/* I currently assume that the hotkey information used in the menu bar is NOT -** used for any actual actions on behalf of the interpreter. -*/ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/event.h" -#include "sci/engine/state.h" -#include "sci/gfx/menubar.h" -#include "sci/gui/gui.h" -#include "sci/engine/kernel.h" - -namespace Sci { - - -/* Copies a string into a newly allocated memory part, up to a certain length. -** Parameters: (char *) src: The source string -** (int) length: The maximum length of the string (not counting -** a trailing \0). -** Returns : (char *) The resulting copy, allocated with malloc(). -** To free this string, use the free() command. -** See _SCI_MALLOC() for more information if call fails. -*/ -char *sci_strndup(const char *src, size_t length) { - assert(src); - - size_t rlen = (int)MIN(strlen(src), length) + 1; - char *strres = (char *)malloc(rlen); - assert(strres); - - strncpy(strres, src, rlen); - strres[rlen - 1] = 0; - - return strres; -} - - -#define SIZE_INF 32767 - -Menu::Menu() { - _titleWidth = 0; - _width = 0; -} - -MenuItem::MenuItem() { - _type = MENU_TYPE_NORMAL; - _flags = 0; - memset(_said, 0, sizeof(_said)); - _saidPos = NULL_REG; - _textPos = NULL_REG; - _modifiers = 0; - _key = 0; - _enabled = 0; - _tag = 0; -} - -int Menu::addMenuItem(GfxState *state, MenuType type, const char *left, const char *right, - int font, int key, int modifiers, int tag, reg_t text_pos) { -// Returns the total text size, plus MENU_BOX_CENTER_PADDING if (right != NULL) - MenuItem newItem; - MenuItem *item; - int total_left_size = 0; - int16 width = 10, height = 10; - EngineState *s = ((SciEngine *)g_engine)->getEngineState(); // HACK - - item = &newItem; - item->_type = type; - - if (type == MENU_TYPE_HBAR) { - _items.push_back(newItem); - return 0; - } - - // else assume MENU_TYPE_NORMAL - item->_text = left; - if (right) { - item->_keytext = right; - item->_keytext.trim(); // Remove trailing whitespace - item->_flags = MENU_ATTRIBUTE_FLAGS_KEY; - item->_key = key; - item->_modifiers = modifiers; - } else { - item->_flags = 0; - } - - if (right) { - s->_gui->textSize(item->_keytext.c_str(), font, -1, &width, &height); - total_left_size = MENU_BOX_CENTER_PADDING + width; - } - - item->_enabled = 1; - item->_tag = tag; - item->_textPos = text_pos; - s->_gui->textSize(left, font, -1, &width, &height); - - _items.push_back(newItem); - - return total_left_size + width; -} - -void Menubar::addMenu(GfxState *state, const Common::String &title, const Common::String &entries, int font, reg_t entries_base) { - char tracker; - char *left = NULL; - reg_t left_origin = entries_base; - int string_len = 0; - int tag = 0, c_width, max_width = 0; - int16 height = 10; - EngineState *s = ((SciEngine *)g_engine)->getEngineState(); // HACK - - Menu menu; - - menu._title = title; - menu._titleWidth = 10; - - s->_gui->textSize(title.c_str(), font, -1, &(menu._titleWidth), &height); - - const char *entries_p = entries.c_str(); - - do { - tracker = *entries_p++; - entries_base.offset++; - - if (!left) { // Left string not finished? - if (tracker == '=') { // Hit early-SCI tag assignment? - left = sci_strndup(entries_p - string_len - 1, string_len); - tag = atoi(entries_p++); - tracker = *entries_p++; - } - if ((tracker == 0 && string_len > 0) || (tracker == '=') || (tracker == ':')) { // End of entry - MenuType entrytype = MENU_TYPE_NORMAL; - char *inleft; - reg_t beginning; - - if (!left) - left = sci_strndup(entries_p - string_len - 1, string_len); - - inleft = left; - while (isspace((unsigned char)*inleft)) - inleft++; // Seek beginning of actual string - - if (!strncmp(inleft, MENU_HBAR_STRING_1, strlen(MENU_HBAR_STRING_1)) - || !strncmp(inleft, MENU_HBAR_STRING_2, strlen(MENU_HBAR_STRING_2)) - || !strncmp(inleft, MENU_HBAR_STRING_3, strlen(MENU_HBAR_STRING_3))) { - entrytype = MENU_TYPE_HBAR; // Horizontal bar - free(left); - left = NULL; - } - - beginning = entries_base; - beginning.offset -= string_len + 1; -#ifdef INCLUDE_OLDGFX - c_width = menu.addMenuItem(state, entrytype, left, NULL, font, 0, 0, tag, beginning); -#endif - if (c_width > max_width) - max_width = c_width; - - string_len = 0; - free(left); - left = NULL; // Start over - } else if (tracker == '`') { // Start of right string - if (!left) { - left_origin = entries_base; - left_origin.offset -= string_len + 1; - left = sci_strndup(entries_p - string_len - 1, string_len); - } - string_len = 0; // Continue with the right string - } else - string_len++; // Nothing special - - } else { // Left string finished => working on right string - if ((tracker == ':') || (tracker == 0)) { // End of entry - int key, modifiers = 0; - - char *right = sci_strndup(entries_p - string_len - 1, string_len); - - if (right[0] == '#') { - right[0] = SCI_SPECIAL_CHAR_FUNCTION; // Function key - - key = SCI_KEY_F1 + ((right[1] - '1') << 8); - - if (right[1] == '0') - key = SCI_KEY_F10; // F10 - - if (right[2] == '=') { - tag = atoi(right + 3); - right[2] = 0; - }; - } else if (right[0] == '@') { // Alt key - right[0] = SCI_SPECIAL_CHAR_ALT; // ALT - key = right[1]; - modifiers = SCI_KEYMOD_ALT; - - if ((key >= 'a') && (key <= 'z')) - right[1] = key - 'a' + 'A'; - - if (right[2] == '=') { - tag = atoi(right + 3); - right[2] = 0; - } - } else { - if (right[0] == '^') { - right[0] = SCI_SPECIAL_CHAR_CTRL; // Control key - there must be a replacement... - key = right[1]; - modifiers = SCI_KEYMOD_CTRL; - - if ((key >= 'a') && (key <= 'z')) - right[1] = key - 'a' + 'A'; - - if (right[2] == '=') { - tag = atoi(right + 3); - right[2] = 0; - } - } else { - key = right[0]; - if ((key >= 'a') && (key <= 'z')) - right[0] = key - 'a' + 'A'; - - if (right[1] == '=') { - tag = atoi(right + 2); - right[1] = 0; - } - } - if ((key >= 'A') && (key <= 'Z')) - key = key - 'A' + 'a'; // Lowercase the key - } - - int i = strlen(right); - - while (i > 0 && right[--i] == ' ') - right[i] = 0; // Cut off chars to the right - - c_width = menu.addMenuItem(state, MENU_TYPE_NORMAL, left, right, font, key, - modifiers, tag, left_origin); - tag = 0; - if (c_width > max_width) - max_width = c_width; - - string_len = 0; - free(right); - free(left); - left = NULL; // Start over - - } else - string_len++; // continuing entry - } // right string finished - } while (tracker); - - menu._width = max_width; - - _menus.push_back(menu); -} - -bool MenuItem::matchKey(int message, int modifiers) { - if ((_key == message) && ((modifiers & (SCI_KEYMOD_CTRL | SCI_KEYMOD_ALT)) == _modifiers)) - return true; - - if (message == '\t' && _key == 'i' && ((modifiers & (SCI_KEYMOD_CTRL | SCI_KEYMOD_ALT)) == 0) && _modifiers == SCI_KEYMOD_CTRL) - return true; // Match TAB to ^I - - return 0; -} - -int Menubar::setAttribute(EngineState *s, int menu_nr, int item_nr, int attribute, reg_t value) { - MenuItem *item; - - if ((menu_nr < 0) || (item_nr < 0)) - return 1; - - if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size())) - return 1; - - item = &_menus[menu_nr]._items[item_nr]; - - switch (attribute) { - - case MENU_ATTRIBUTE_SAID: - if (value.segment) { - item->_saidPos = value; - s->_segMan->memcpy(item->_said, value, MENU_SAID_SPEC_SIZE); // Copy Said spec - item->_flags |= MENU_ATTRIBUTE_FLAGS_SAID; - - } else - item->_flags &= ~MENU_ATTRIBUTE_FLAGS_SAID; - - break; - - case MENU_ATTRIBUTE_TEXT: - assert(value.segment); - item->_text = s->_segMan->getString(value); - item->_textPos = value; - break; - - case MENU_ATTRIBUTE_KEY: - item->_keytext.clear(); - - if (value.segment) { - - // FIXME: What happens here if <value> is an extended key? Potential bug. LS - item->_key = value.offset; - item->_modifiers = 0; - item->_keytext = value.offset; - item->_flags |= MENU_ATTRIBUTE_FLAGS_KEY; - if ((item->_key >= 'A') && (item->_key <= 'Z')) - item->_key = item->_key - 'A' + 'a'; // Lowercase the key - } else { - item->_flags &= ~MENU_ATTRIBUTE_FLAGS_KEY; - } - break; - - case MENU_ATTRIBUTE_ENABLED: - item->_enabled = value.offset; - break; - - case MENU_ATTRIBUTE_TAG: - item->_tag = value.offset; - break; - - default: - error("Attempt to set invalid attribute of menu %d, item %d: 0x%04x", menu_nr, item_nr, attribute); - return 1; - } - - return 0; -} - -reg_t Menubar::getAttribute(int menu_nr, int item_nr, int attribute) const { - if ((menu_nr < 0) || (item_nr < 0)) - return SIGNAL_REG; - - if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size())) - return SIGNAL_REG; - - const MenuItem &item = _menus[menu_nr]._items[item_nr]; - - switch (attribute) { - case MENU_ATTRIBUTE_SAID: - return item._saidPos; - - case MENU_ATTRIBUTE_TEXT: - return item._textPos; - - case MENU_ATTRIBUTE_KEY: - return make_reg(0, item._key); - - case MENU_ATTRIBUTE_ENABLED: - return make_reg(0, item._enabled); - - case MENU_ATTRIBUTE_TAG: - return make_reg(0, item._tag); - - default: - warning("Attempt to read invalid attribute from menu %d, item %d: 0x%04x", menu_nr, item_nr, attribute); - return SIGNAL_REG; - } -} - -bool Menubar::itemValid(int menu_nr, int item_nr) const { - if ((menu_nr < 0) || (item_nr < 0)) - return false; - - if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size())) - return false; - - const MenuItem &item = _menus[menu_nr]._items[item_nr]; - - if ((item._type == MENU_TYPE_NORMAL) && item._enabled) - return true; - - return false; // May not be selected -} - -bool Menubar::mapPointer(const Common::Point &pointerPos, int &menu_nr, int &item_nr, Common::Rect portBounds) const { - - if (pointerPos.y <= 10) { // Re-evaulate menu - int x = MENU_LEFT_BORDER; - - for (uint i = 0; i < _menus.size(); i++) { - int newx = x + MENU_BORDER_SIZE * 2 + _menus[i]._titleWidth; - - if (pointerPos.x < x) - return false; - - if (pointerPos.x < newx) { - menu_nr = i; - item_nr = -1; - } - - x = newx; - } - } else { - int row = (pointerPos.y / 10) - 1; - - if ((menu_nr < 0) || (menu_nr >= (int)_menus.size())) - return true; // No menu - - const Menu &menu = _menus[menu_nr]; // Menu is valid, assume that it's popped up - - if ((int)menu._items.size() <= row) - return true; - - if ((pointerPos.x < portBounds.left) || (pointerPos.x > portBounds.right)) - return true; - - if (itemValid(menu_nr, row)) - item_nr = row; // Only modify if we'll be hitting a valid element - - } - - return false; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/menubar.h b/engines/sci/gfx/menubar.h deleted file mode 100644 index 6208c16e02..0000000000 --- a/engines/sci/gfx/menubar.h +++ /dev/null @@ -1,232 +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. - * - * $URL$ - * $Id$ - * - */ - -/* Header for SCI0 menu bar management */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_SCI_MENUBAR_H -#define SCI_GFX_SCI_MENUBAR_H - -#include "sci/engine/vm_types.h" -#include "sci/gfx/operations.h" - -#include "common/array.h" -#include "common/rect.h" - -namespace Sci { - -struct EngineState; - -#define MENU_HBAR_STRING_1 "--!" -#define MENU_HBAR_STRING_2 "-!" -#define MENU_HBAR_STRING_3 "!--" -/* These strings are used in SCI to determine an empty menu line */ - -#define MENU_BORDER_SIZE 0 -/* The number of pixels added to the left and right to the text of a menu on the menu bar */ - -#define MENU_LEFT_BORDER 5 -/* The number of pixels added to the left of the first menu */ - -#define MENU_BOX_CENTER_PADDING 10 -/* Number of pixels to leave in between the left and the right centered text content in boxes that use right centered content */ - -#define MENU_BOX_LEFT_PADDING 0 -/* Number of pixels to pad to the left */ -#define MENU_BOX_RIGHT_PADDING 2 -/* Number of pixels to pad to the right */ - -#define MENU_BAR_HEIGHT 10 - - -/* Special characters used while building the menu bar */ -#define SCI_SPECIAL_CHAR_FUNCTION 'F' -#define SCI_SPECIAL_CHAR_CTRL 3 -#define SCI_SPECIAL_CHAR_ALT 2 - -/* Maximum number of bytes per SAID spec */ -#define MENU_SAID_SPEC_SIZE 64 - -#define MENU_ATTRIBUTE_SAID 0x6d -#define MENU_ATTRIBUTE_TEXT 0x6e -#define MENU_ATTRIBUTE_KEY 0x6f -#define MENU_ATTRIBUTE_ENABLED 0x70 -#define MENU_ATTRIBUTE_TAG 0x71 - -/* Those flags determine whether the corresponding MenuItem entries are valid */ -#define MENU_ATTRIBUTE_FLAGS_KEY 0x01 -#define MENU_ATTRIBUTE_FLAGS_SAID 0x02 - - -enum MenuType { - MENU_TYPE_NORMAL = 0, - MENU_TYPE_HBAR = 1 /* Horizontal bar */ -}; - -class MenuItem : public Common::Serializable { -public: - MenuType _type; /**< Normal or hbar */ - Common::String _keytext; /**< right-centered part of the text (the key) */ - - int _flags; - byte _said[MENU_SAID_SPEC_SIZE]; /**< Said spec for this item */ - reg_t _saidPos; - Common::String _text; - reg_t _textPos; - int _modifiers; /**< Hotkey for this item */ - int _key; /**< Hotkey for this item */ - int _enabled; - int _tag; - -public: - MenuItem(); - - virtual void saveLoadWithSerializer(Common::Serializer &ser); - - /** - * Determines whether a message/modifiers key pair matches a menu item's key parameters. - * - * @param[in] message The message to match - * @param[in] modifiers The modifier flags to match - * @return true on match, false otherwise - */ - bool matchKey(int message, int modifiers); -}; - - -class Menu : public Common::Serializable { -public: - Common::String _title; - - /** Width of the title in pixels */ - int16 _titleWidth; - - /** Pixel width of the menu window */ - int16 _width; - - /** - * Actual entries into the menu. - * Window height equals to number of items times 10. - */ - Common::Array<MenuItem> _items; - -public: - Menu(); - - virtual void saveLoadWithSerializer(Common::Serializer &ser); - -//protected: - // FIXME: This should be (partially) turned into a MenuItem constructor - int addMenuItem(GfxState *state, MenuType type, const char *left, const char *right, - int font, int key, int modifiers, int tag, reg_t text_pos); -}; - - - - -class Menubar : public Common::Serializable { -public: - /** The actual menus. */ - Common::Array<Menu> _menus; - -public: - virtual void saveLoadWithSerializer(Common::Serializer &ser); - - /** - * Adds a menu to the menubar. - * - * The menu entries use the following special characters: - * '`' : Right justify the following part - * ':' : End of this entry - * '#' : Function key (replaced by 'F') - * '^' : Control key (replaced by \002, which looks like "CTRL") - * '=' : Initial tag value - * and the special string "--!", which represents a horizontal bar in the - * menu. - * - * @param[in] state The state the fonts are stored in - * @param[in] title The menu title - * @param[in] entries A string of menu entries - * @param[in] font The font which is to be used for drawing - * @param[in] entries_base Segmented VM address of the entries string - */ - void addMenu(GfxState *state, const Common::String &title, const Common::String &entries, int font, reg_t entries_base); - - /** - * Sets the attributes for a menu item. - * - * @param[in] s The current state - * @param[in] menu The menu number to edit - * @param[in] item The menu item to change - * @param[in] attribute The attribute to modify - * @param[in] value The value the attribute should be set to - * @return 0 on success, 1 if either menu or item were invalid - */ - int setAttribute(EngineState *s, int menu, int item, int attribute, reg_t value); - - - /** - * Gets an attribute for a menuitem. - * - * @param[in] menu The menu number - * @param[in] item The menu item to read - * @param[in] attribute The attribute to read from - * @return The attribute value, or -1 on error - */ - reg_t getAttribute(int menu, int item, int attribute) const; - - - /** - * Determines whether the specified menu entry may be activated. - * - * @return true if the menu item may be selected, false otherwise - */ - bool itemValid(int menu, int item) const; - - - /** - * Maps the pointer position to a (menu,item) tuple. - * - * @param[in] pointerPos the current pointer position - * @param[in] menu_nr the current menu (updated by this function if - * necessary) - * @param[in] item_nr the current menu item (updated by this function - * if necessary) - * @param[in] portBounds the port bounds of the currently active menu (if any) - * @return true if the pointer is outside a valid port, - * false otherwise. - */ - bool mapPointer(const Common::Point &pointerPos, int &menu_nr, int &item_nr, Common::Rect portBounds) const; - -}; - -} // End of namespace Sci - -#endif // SCI_GFX_SCI_MENUBAR_H - -#endif - diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp deleted file mode 100644 index a2791794fd..0000000000 --- a/engines/sci/gfx/operations.cpp +++ /dev/null @@ -1,1212 +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. - * - * $URL$ - * $Id$ - * - */ - -// Graphical operations, called from the widget state manager - -#include "sci/sci.h" -#include "sci/gfx/operations.h" -#ifdef INCLUDE_OLDGFX -#include "sci/gui32/font.h" -#endif -#include "sci/console.h" -#include "sci/event.h" - -#include "common/system.h" -#include "common/events.h" - -namespace Sci { - -#ifdef INCLUDE_OLDGFX - -#define PRECISE_PRIORITY_MAP // Duplicate all operations on the local priority map as appropriate - -#undef GFXW_DEBUG_DIRTY -// Enable to debug stuff relevant for dirty rectsin widget management - -#ifdef GFXW_DEBUG_DIRTY -# define DDIRTY fprintf(stderr, "%s:%5d| ", __FILE__, __LINE__); fprintf -#else -# define DDIRTY if (0) fprintf -#endif - -// Default color maps -#define DEFAULT_COLORS_NR 16 - -PaletteEntry default_colors[DEFAULT_COLORS_NR] = { - PaletteEntry(0x00, 0x00, 0x00), PaletteEntry(0x00, 0x00, 0xaa), - PaletteEntry(0x00, 0xaa, 0x00), PaletteEntry(0x00, 0xaa, 0xaa), - PaletteEntry(0xaa, 0x00, 0x00), PaletteEntry(0xaa, 0x00, 0xaa), - PaletteEntry(0xaa, 0x55, 0x00), PaletteEntry(0xaa, 0xaa, 0xaa), - PaletteEntry(0x55, 0x55, 0x55), PaletteEntry(0x55, 0x55, 0xff), - PaletteEntry(0x55, 0xff, 0x55), PaletteEntry(0x55, 0xff, 0xff), - PaletteEntry(0xff, 0x55, 0x55), PaletteEntry(0xff, 0x55, 0xff), - PaletteEntry(0xff, 0xff, 0x55), PaletteEntry(0xff, 0xff, 0xff) -}; // "Normal" EGA - -#define POINTER_VISIBLE_BUT_CLIPPED 2 - -// How to determine whether colors have to be allocated -#define SCREEN_PALETTE state->driver->getMode()->palette - -//#define GFXOP_DEBUG_DIRTY - -// Internal operations - -static void _gfxop_scale_rect(rect_t *rect, gfx_mode_t *mode) { - rect->x *= mode->scaleFactor; - rect->y *= mode->scaleFactor; - rect->width *= mode->scaleFactor; - rect->height *= mode->scaleFactor; -} - -static void _gfxop_scale_point(Common::Point *point, gfx_mode_t *mode) { - point->x *= mode->scaleFactor; - point->y *= mode->scaleFactor; -} - -int _gfxop_clip(rect_t *rect, rect_t clipzone) { -// Returns 1 if nothing is left */ -#if 0 - printf("Clipping (%d, %d) size (%d, %d) by (%d,%d)(%d,%d)\n", rect->x, rect->y, rect->width, rect->height, - clipzone.x, clipzone.y, clipzone.width, clipzone.height); -#endif - - if (rect->x < clipzone.x) { - rect->width -= (clipzone.x - rect->x); - rect->x = clipzone.x; - } - - if (rect->y < clipzone.y) { - rect->height -= (clipzone.y - rect->y); - rect->y = clipzone.y; - } - - if (rect->x + rect->width > clipzone.x + clipzone.width) - rect->width = (clipzone.x + clipzone.width) - rect->x; - - if (rect->y + rect->height > clipzone.y + clipzone.height) - rect->height = (clipzone.y + clipzone.height) - rect->y; - - if (rect->width < 0) - rect->width = 0; - if (rect->height < 0) - rect->height = 0; - -#if 0 - printf(" => (%d, %d) size (%d, %d)\n", rect->x, rect->y, rect->width, rect->height); -#endif - return (rect->width <= 0 || rect->height <= 0); -} - -static void _gfxop_grab_pixmap(GfxState *state, gfx_pixmap_t **pxmp, int x, int y, - int xl, int yl, int priority, rect_t *zone) { - // Returns 1 if the resulting data size was zero, GFX_OK or an error code otherwise */ - int xfact = state->driver->getMode()->scaleFactor; - int yfact = state->driver->getMode()->scaleFactor; - int unscaled_xl = (xl + xfact - 1) / xfact; - int unscaled_yl = (yl + yfact - 1) / yfact; - *zone = gfx_rect(x, y, xl, yl); - - if (_gfxop_clip(zone, gfx_rect(0, 0, 320 * state->driver->getMode()->scaleFactor, 200 * state->driver->getMode()->scaleFactor))) - error("_gfxop_grab_pixmap: zone was empty"); - - if (!*pxmp) - *pxmp = gfx_new_pixmap(unscaled_xl, unscaled_yl, GFX_RESID_NONE, 0, 0); - else - if (xl * yl > (*pxmp)->width * (*pxmp)->height) { - free((*pxmp)->data); - (*pxmp)->data = NULL; - } - - if (!(*pxmp)->data) { - (*pxmp)->index_width = unscaled_xl + 1; - (*pxmp)->index_height = unscaled_yl + 1; - gfx_pixmap_alloc_data(*pxmp, state->driver->getMode()); - } - state->driver->grabPixmap(*zone, *pxmp, priority ? GFX_MASK_PRIORITY : GFX_MASK_VISUAL); -} - -#define DRAW_LOOP(condition) \ -{ \ - rect_t drawrect = gfx_rect(pos.x, pos.y, pxm->index_width, pxm->index_height); \ - int offset, base_offset; \ - int read_offset, base_read_offset; \ - int x,y; \ - \ - if (!pxm->index_data) { \ - error("Attempt to draw control color %d on pixmap %d/%d/%d without index data", color, pxm->ID, pxm->loop, pxm->cel); \ - return; \ - } \ - \ - if (_gfxop_clip(&drawrect, gfx_rect(0, 0, 320, 200))) \ - return; \ - \ - offset = base_offset = drawrect.x + drawrect.y * 320; \ - read_offset = base_read_offset = (drawrect.x - pos.x) + ((drawrect.y - pos.y) * pxm->index_width); \ - \ - for (y = 0; y < drawrect.height; y++) { \ - for (x = 0; x < drawrect.width; x++) \ - if (pxm->index_data[read_offset++] != pxm->color_key) { \ - if (condition) \ - map->index_data[offset++] = color; \ - else \ - ++offset; \ - } else \ - ++offset; \ - \ - offset = base_offset += 320; \ - read_offset = base_read_offset += pxm->index_width; \ - } \ -} - -static void _gfxop_draw_control(gfx_pixmap_t *map, gfx_pixmap_t *pxm, int color, Common::Point pos) -DRAW_LOOP(1) // Always draw - -#ifdef PRECISE_PRIORITY_MAP -static void _gfxop_draw_priority(gfx_pixmap_t *map, gfx_pixmap_t *pxm, int color, Common::Point pos) -DRAW_LOOP(map->index_data[offset] < color) // Draw only lower priority -#endif - -#undef DRAW_LOOP - -static void _gfxop_install_pixmap(GfxDriver *driver, gfx_pixmap_t *pxm) { - if (!driver->getMode()->palette) - return; - if (!pxm->palette) - return; - - pxm->palette->mergeInto(driver->getMode()->palette); - assert(pxm->palette->getParent() == driver->getMode()->palette); - - if (pxm->palette_revision != pxm->palette->getRevision()) - gfx_xlate_pixmap(pxm, driver->getMode()); - - if (!driver->getMode()->palette->isDirty()) - return; - - // TODO: We probably want to only update the colours used by this pixmap - // here. This will require updating the 'dirty' system. - byte paletteData[4*256]; - const uint paletteSize = driver->getMode()->palette->size(); - for (uint i = 0; i < paletteSize; ++i) { - const PaletteEntry& c = (*driver->getMode()->palette)[i]; - paletteData[4*i+0] = c.r; - paletteData[4*i+1] = c.g; - paletteData[4*i+2] = c.b; - paletteData[4*i+3] = 255; - } - - g_system->setPalette(paletteData, 0, paletteSize); - driver->getMode()->palette->markClean(); -} - -static void _gfxop_draw_pixmap(GfxDriver *driver, gfx_pixmap_t *pxm, int priority, int control, - rect_t src, rect_t dest, rect_t clip, int static_buf, gfx_pixmap_t *control_map, gfx_pixmap_t *priority_map) { - rect_t clipped_dest = gfx_rect(dest.x, dest.y, dest.width, dest.height); - - if (control >= 0 || priority >= 0) { - Common::Point original_pos = Common::Point(dest.x / driver->getMode()->scaleFactor, dest.y / driver->getMode()->scaleFactor); - - if (control >= 0) - _gfxop_draw_control(control_map, pxm, control, original_pos); - -#ifdef PRECISE_PRIORITY_MAP - if (priority >= 0) - _gfxop_draw_priority(priority_map, pxm, priority, original_pos); -#endif - } - - if (_gfxop_clip(&clipped_dest, clip)) - return; - - src.x += clipped_dest.x - dest.x; - src.y += clipped_dest.y - dest.y; - src.width = clipped_dest.width; - src.height = clipped_dest.height; - - _gfxop_install_pixmap(driver, pxm); - - DDIRTY(stderr, "\\-> Drawing to actual %d %d %d %d\n", clipped_dest.x / driver->getMode()->scaleFactor, - clipped_dest.y / driver->getMode()->scaleFactor, clipped_dest.width / driver->getMode()->scaleFactor, clipped_dest.height / driver->getMode()->scaleFactor); - - driver->drawPixmap(pxm, priority, src, clipped_dest, static_buf ? GFX_BUFFER_STATIC : GFX_BUFFER_BACK); -} - -static void _gfxop_buffer_propagate_box(GfxState *state, rect_t box, gfx_buffer_t buffer) { - if (_gfxop_clip(&box, gfx_rect(0, 0, 320 * state->driver->getMode()->scaleFactor, 200 * state->driver->getMode()->scaleFactor))) - return; - - state->driver->update(box, Common::Point(box.x, box.y), buffer); -} - -//** Dirty rectangle operations ** - -static void _gfxop_update_box(GfxState *state, rect_t box) { - _gfxop_scale_rect(&box, state->driver->getMode()); - _gfxop_buffer_propagate_box(state, box, GFX_BUFFER_FRONT); -} - -void gfxdr_add_dirty(DirtyRectList &list, rect_t box) { - if (box.width < 0) { - box.x += box.width; - box.width = - box.width; - } - - if (box.height < 0) { - box.y += box.height; - box.height = - box.height; - } -#ifdef GFXOP_DEBUG_DIRTY - fprintf(stderr, "Adding new dirty (%d %d %d %d)\n", - GFX_PRINT_RECT(box)); -#endif - if (_gfxop_clip(&box, gfx_rect(0, 0, 320, 200))) - return; - - DirtyRectList::iterator dirty = list.begin(); - while (dirty != list.end()) { - if (gfx_rects_overlap(*dirty, box)) { - Common::Rect tmp = toCommonRect(box); - tmp.extend(toCommonRect(*dirty)); - box = toSCIRect(tmp); - - dirty = list.erase(dirty); - } else - ++dirty; - } - list.push_back(box); -} - -static void _gfxop_add_dirty(GfxState *state, rect_t box) { - if (state->disable_dirty) - return; - - gfxdr_add_dirty(state->_dirtyRects, box); -} - -static void _gfxop_add_dirty_x(GfxState *state, rect_t box) { - // Extends the box size by one before adding (used for lines) - if (box.width < 0) - box.width--; - else - box.width++; - - if (box.height < 0) - box.height--; - else - box.height++; - - _gfxop_add_dirty(state, box); -} - -static void _gfxop_clear_dirty_rec(GfxState *state, DirtyRectList &dirtyRects) { - DirtyRectList::iterator dirty = dirtyRects.begin(); - while (dirty != dirtyRects.end()) { - - #ifdef GFXOP_DEBUG_DIRTY - fprintf(stderr, "\tClearing dirty (%d %d %d %d)\n", GFX_PRINT_RECT(*dirty)); - #endif - _gfxop_update_box(state, *dirty); - ++dirty; - } - dirtyRects.clear(); -} - -//** Exported operations ** - -static void init_aux_pixmap(gfx_pixmap_t **pixmap) { - *pixmap = gfx_pixmap_alloc_index_data(gfx_new_pixmap(320, 200, GFX_RESID_NONE, 0, 0)); - // FIXME: don't duplicate this palette for every aux_pixmap - (*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR); -} - -void gfxop_init(GfxState *state, ResourceManager *resMan, - SciGuiScreen *screen, SciGuiPalette *palette, int scaleFactor) { - state->visible_map = GFX_MASK_VISUAL; - state->disable_dirty = 0; - state->pic = state->pic_unscaled = NULL; - state->pic_nr = -1; // Set background pic number to an invalid value - state->tag_mode = 0; - state->_dirtyRects.clear(); - - // Jones in the Fast Lane uses up the whole window - if (!scumm_stricmp(((SciEngine *)g_engine)->getGameID(), "jones")) - state->pic_port_bounds = gfx_rect(0, 0, 320, 200); - else - state->pic_port_bounds = gfx_rect(0, 10, 320, 190); - - state->driver = new GfxDriver(screen, scaleFactor); - - state->gfxResMan = new GfxResManager(state->driver, resMan, screen, palette, toCommonRect(state->pic_port_bounds)); - - gfxop_set_clip_zone(state, gfx_rect(0, 0, 320, 200)); - - init_aux_pixmap(&(state->control_map)); - init_aux_pixmap(&(state->priority_map)); - init_aux_pixmap(&(state->static_priority_map)); -} - -void gfxop_exit(GfxState *state) { - state->gfxResMan->freeResManager(); - - if (state->control_map) { - gfx_free_pixmap(state->control_map); - state->control_map = NULL; - } - - if (state->priority_map) { - gfx_free_pixmap(state->priority_map); - state->priority_map = NULL; - } - - if (state->static_priority_map) { - gfx_free_pixmap(state->static_priority_map); - state->static_priority_map = NULL; - } - - delete state->driver; -} - -static int _gfxop_scan_one_bitmask(gfx_pixmap_t *pixmap, rect_t zone) { - int retval = 0; - int pixmap_xscale = pixmap->index_width / 320; - int pixmap_yscale = pixmap->index_height / 200; - int line_width = pixmap_yscale * pixmap->index_width; - int startindex = (line_width * zone.y) + (zone.x * pixmap_xscale); - - startindex += pixmap_xscale >> 1; // Center on X - startindex += (pixmap_yscale >> 1) * pixmap->index_width; // Center on Y - - if (_gfxop_clip(&zone, gfx_rect(0, 0, pixmap->index_width, pixmap->index_height))) - return 0; - - while (zone.height--) { - int i; - for (i = 0; i < (zone.width * pixmap_xscale); i += pixmap_xscale) - retval |= (1 << ((pixmap->index_data[startindex + i]) & 0xf)); - - startindex += line_width; - } - - return retval; -} - -int gfxop_scan_bitmask(GfxState *state, rect_t area, gfx_map_mask_t map) { - gfxr_pic_t *pic = (state->pic_unscaled) ? state->pic_unscaled : state->pic; - int retval = 0; - - _gfxop_clip(&area, gfx_rect(0, 10, 320, 200)); - - if (area.width <= 0 - || area.height <= 0) - return 0; - - if (map & GFX_MASK_VISUAL) - retval |= _gfxop_scan_one_bitmask(pic->visual_map, area); - - if (map & GFX_MASK_PRIORITY) - retval |= _gfxop_scan_one_bitmask(state->priority_map, area); - if (map & GFX_MASK_CONTROL) - retval |= _gfxop_scan_one_bitmask(state->control_map, area); - - return retval; -} - -#define MIN_X 0 -#define MIN_Y 0 -#define MAX_X 319 -#define MAX_Y 199 - -void gfxop_set_clip_zone(GfxState *state, rect_t zone) { - int xfact, yfact; - - DDIRTY(stderr, "-- Setting clip zone %d %d %d %d\n", GFX_PRINT_RECT(zone)); - - xfact = state->driver->getMode()->scaleFactor; - yfact = state->driver->getMode()->scaleFactor; - - if (zone.x < MIN_X) { - zone.width -= (zone.x - MIN_X); - zone.x = MIN_X; - } - - if (zone.y < MIN_Y) { - zone.height -= (zone.y - MIN_Y); - zone.y = MIN_Y; - } - - if (zone.x + zone.width > MAX_X) - zone.width = MAX_X + 1 - zone.x; - - if (zone.y + zone.height > MAX_Y) - zone.height = MAX_Y + 1 - zone.y; - - memcpy(&(state->clip_zone_unscaled), &zone, sizeof(rect_t)); - - state->clip_zone.x = state->clip_zone_unscaled.x * xfact; - state->clip_zone.y = state->clip_zone_unscaled.y * yfact; - state->clip_zone.width = state->clip_zone_unscaled.width * xfact; - state->clip_zone.height = state->clip_zone_unscaled.height * yfact; -} - -void gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, int a, int priority, int control) { - int mask = ((r >= 0 && g >= 0 && b >= 0) ? GFX_MASK_VISUAL : 0) | ((priority >= 0) ? GFX_MASK_PRIORITY : 0) - | ((control >= 0) ? GFX_MASK_CONTROL : 0); - - if (a >= GFXOP_ALPHA_THRESHOLD) - mask &= ~GFX_MASK_VISUAL; - - color->mask = mask; - - color->priority = priority; - color->control = control; - - if (mask & GFX_MASK_VISUAL) { - color->visual.r = r; - color->visual.g = g; - color->visual.b = b; - color->alpha = a; - color->visual._parentIndex = SCREEN_PALETTE->findNearbyColor(r,g,b,true); - } -} - -// Wrapper for gfxop_set_color -void gfxop_set_color(GfxState *state, gfx_color_t *colorOut, gfx_color_t &colorIn) { - gfxop_set_color(state, colorOut, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.visual.r : -1, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.visual.g : -1, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.visual.b : -1, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.alpha : -1, - (colorIn.mask & GFX_MASK_PRIORITY) ? colorIn.priority : -1, - (colorIn.mask & GFX_MASK_CONTROL) ? colorIn.control : -1); -} - -// Generic drawing operations - -static int line_check_bar(int *start, int *length, int clipstart, int cliplength) { - int overlength; - - if (*start < clipstart) { - *length -= (clipstart - *start); - *start = clipstart; - } - - overlength = 1 + (*start + *length) - (clipstart + cliplength); - - if (overlength > 0) - *length -= overlength; - - return (*length < 0); -} - -static void clip_line_partial(float *start, float *end, float delta_val, float pos_val, float start_val, float end_val) { - float my_start = (start_val - pos_val) * delta_val; - float my_end = (end_val - pos_val) * delta_val; - - if (my_end < *end) - *end = my_end; - if (my_start > *start) - *start = my_start; -} - -static int line_clip(rect_t *line, rect_t clip, int xfact, int yfact) { - // returns 1 if nothing is left, or 0 if part of the line is in the clip window - // Compensate for line thickness (should match precisely) - clip.width -= xfact; - clip.height -= yfact; - - if (!line->width) { // vbar - if (line->x < clip.x || line->x >= (clip.x + clip.width)) - return 1; - - return line_check_bar(&(line->y), &(line->height), clip.y, clip.height); - - } else { - if (!line->height) {// hbar - if (line->y < clip.y || line->y >= (clip.y + clip.height)) - return 1; - - return line_check_bar(&(line->x), &(line->width), clip.x, clip.width); - - } else { // "normal" line - float start = 0.0f, end = 1.0f; - float xv = (float)line->width; - float yv = (float)line->height; - - if (line->width < 0) - clip_line_partial(&start, &end, (float)(1.0 / xv), (float)line->x, (float)(clip.x + clip.width), (float)clip.x); - else - clip_line_partial(&start, &end, (float)(1.0 / xv), (float)line->x, (float)clip.x, (float)(clip.x + clip.width)); - - if (line->height < 0) - clip_line_partial(&start, &end, (float)(1.0 / yv), (float)line->y, (float)(clip.y + clip.height), (float)clip.y); - else - clip_line_partial(&start, &end, (float)(1.0 / yv), (float)line->y, (float)clip.y, (float)(clip.y + clip.height)); - - line->x += (int)(xv * start); - line->y += (int)(yv * start); - - line->width = (int)(xv * (end - start)); - line->height = (int)(yv * (end - start)); - - return (start > 1.0f || end < 0.0f); - } - } - - return 0; -} - -static int point_clip(Common::Point *start, Common::Point *end, rect_t clip, int xfact, int yfact) { - rect_t line = gfx_rect(start->x, start->y, end->x - start->x, end->y - start->y); - int retval = line_clip(&line, clip, xfact, yfact); - - start->x = line.x; - start->y = line.y; - - end->x = line.x + line.width; - end->y = line.y + line.height; - - return retval; -} - -static void draw_line_to_control_map(GfxState *state, Common::Point start, Common::Point end, gfx_color_t color) { - if (color.mask & GFX_MASK_CONTROL) - if (!point_clip(&start, &end, state->clip_zone_unscaled, 0, 0)) - gfx_draw_line_pixmap_i(state->control_map, start, end, color.control); -} - -static void simulate_stippled_line_draw(GfxDriver *driver, int skipone, Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode) { - // Draws a stippled line if this isn't supported by the driver (skipone is ignored ATM) - int xl = end.x - start.x; - int yl = end.y - start.y; - int stepwidth = (xl) ? driver->getMode()->scaleFactor : driver->getMode()->scaleFactor; - int dbl_stepwidth = 2 * stepwidth; - int linelength = (line_mode == GFX_LINE_MODE_FINE) ? stepwidth - 1 : 0; - int16 *posvar; - int length; - int delta; - int length_left; - - if (!xl) { // xl = 0, so we move along yl - posvar = &start.y; - length = yl; - delta = (yl < 0) ? -dbl_stepwidth : dbl_stepwidth; - } else { - assert(!yl); // We don't do diagonals; that's not needed ATM. - posvar = &start.x; - length = xl; - delta = (xl < 0) ? -dbl_stepwidth : dbl_stepwidth; - } - - length_left = length; - - if (skipone) { - length_left -= stepwidth; - *posvar += stepwidth; - } - - length /= delta; - - length_left -= length * dbl_stepwidth; - - if (xl) - xl = linelength; - else - yl = linelength; - - while (length--) { - Common::Point nextpos = Common::Point(start.x + xl, start.y + yl); - driver->drawLine(start, nextpos, color, line_mode, GFX_LINE_STYLE_NORMAL); - *posvar += delta; - } - - if (length_left) { - Common::Point nextpos; - - if (length_left > stepwidth) - length_left = stepwidth; - - if (xl) - xl = length_left; - else - if (yl) - yl = length_left; - - nextpos = Common::Point(start.x + xl, start.y + yl); - - driver->drawLine(start, nextpos, color, line_mode, GFX_LINE_STYLE_NORMAL); - } -} - -static void _gfxop_draw_line_clipped(GfxState *state, Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, - gfx_line_style_t line_style) { - int skipone = (start.x ^ end.y) & 1; // Used for simulated line stippling - - // First, make sure that the line is normalized - if (start.y > end.y) { - Common::Point swap = start; - start = end; - end = swap; - } - - if (start.x < state->clip_zone.x - || start.y < state->clip_zone.y - || end.x >= (state->clip_zone.x + state->clip_zone.width) - || end.y >= (state->clip_zone.y + state->clip_zone.height)) - if (point_clip(&start, &end, state->clip_zone, state->driver->getMode()->scaleFactor - 1, state->driver->getMode()->scaleFactor - 1)) - return; // Clipped off - - if (line_style == GFX_LINE_STYLE_STIPPLED) { - if (start.x != end.x && start.y != end.y) - error("[GFX] Attempt to draw stippled line which is neither an hbar nor a vbar: (%d,%d) -- (%d,%d)", start.x, start.y, end.x, end.y); - simulate_stippled_line_draw(state->driver, skipone, start, end, color, line_mode); - } - - state->driver->drawLine(start, end, color, line_mode, line_style); -} - -void gfxop_draw_line(GfxState *state, Common::Point start, Common::Point end, - gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style) { - int xfact, yfact; - - _gfxop_add_dirty_x(state, gfx_rect(start.x, start.y, end.x - start.x, end.y - start.y)); - - xfact = state->driver->getMode()->scaleFactor; - yfact = state->driver->getMode()->scaleFactor; - - draw_line_to_control_map(state, start, end, color); - - _gfxop_scale_point(&start, state->driver->getMode()); - _gfxop_scale_point(&end, state->driver->getMode()); - - if (line_mode == GFX_LINE_MODE_FINE) { - start.x += xfact >> 1; - start.y += yfact >> 1; - - end.x += xfact >> 1; - end.y += yfact >> 1; - } - - if (color.visual.getParentIndex() == -1) - gfxop_set_color(state, &color, color); - _gfxop_draw_line_clipped(state, start, end, color, line_mode, line_style); -} - -void gfxop_draw_rectangle(GfxState *state, rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style) { - int xfact, yfact; - int x, y, xl, yl; - Common::Point upper_left_u, upper_right_u, lower_left_u, lower_right_u; - Common::Point upper_left, upper_right, lower_left, lower_right; - - xfact = state->driver->getMode()->scaleFactor; - yfact = state->driver->getMode()->scaleFactor; - - int offset = line_mode == GFX_LINE_MODE_FINE ? 1 : 0; - x = rect.x * xfact + (xfact - 1) * offset; - y = rect.y * yfact + (yfact - 1) * offset; - xl = offset + (rect.width - offset) * xfact; - yl = offset + (rect.height - offset) * yfact; - - upper_left_u = Common::Point(rect.x, rect.y); - upper_right_u = Common::Point(rect.x + rect.width, rect.y); - lower_left_u = Common::Point(rect.x, rect.y + rect.height); - lower_right_u = Common::Point(rect.x + rect.width, rect.y + rect.height); - - upper_left = Common::Point(x, y); - upper_right = Common::Point(x + xl, y); - lower_left = Common::Point(x, y + yl); - lower_right = Common::Point(x + xl, y + yl); - -#define PARTIAL_LINE(pt1, pt2) \ - _gfxop_draw_line_clipped(state, pt1, pt2, color, line_mode, line_style); \ - draw_line_to_control_map(state, pt1##_u, pt2##_u, color); \ - _gfxop_add_dirty_x(state, gfx_rect(pt1##_u.x, pt1##_u.y, pt2##_u.x - pt1##_u.x, pt2##_u.y - pt1##_u.y)) - - PARTIAL_LINE(upper_left, upper_right); - PARTIAL_LINE(upper_right, lower_right); - PARTIAL_LINE(lower_right, lower_left); - PARTIAL_LINE(lower_left, upper_left); - -#undef PARTIAL_LINE -} - - -void gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) { - GfxDriver *drv = state->driver; - int reverse = 0; // switch color1 and color2 - float mod_offset = 0.0f, mod_breadth = 1.0f; // 0.0 to 1.0: Color adjustment - gfx_rectangle_fill_t driver_shade_type; - rect_t new_box; - - shade_type = GFX_BOX_SHADE_FLAT; - - _gfxop_add_dirty(state, box); - - if (color1.mask & GFX_MASK_CONTROL) { - // Write control block, clipped by 320x200 - memcpy(&new_box, &box, sizeof(rect_t)); - _gfxop_clip(&new_box, gfx_rect(0, 0, 320, 200)); - - gfx_draw_box_pixmap_i(state->control_map, new_box, color1.control); - } - - _gfxop_scale_rect(&box, state->driver->getMode()); - - if (!(color1.mask & (GFX_MASK_VISUAL | GFX_MASK_PRIORITY))) - return; - - if (box.width <= 1 || box.height <= 1) { - debugC(2, kDebugLevelGraphics, "Attempt to draw box with size %dx%d", box.width, box.height); - return; - } - - memcpy(&new_box, &box, sizeof(rect_t)); - if (_gfxop_clip(&new_box, state->clip_zone)) - return; - - switch (shade_type) { - - case GFX_BOX_SHADE_FLAT: - driver_shade_type = GFX_SHADE_FLAT; - break; - - case GFX_BOX_SHADE_LEFT: - reverse = 1; - case GFX_BOX_SHADE_RIGHT: - driver_shade_type = GFX_SHADE_HORIZONTALLY; - mod_offset = (float)(((new_box.x - box.x) * 1.0) / (box.width * 1.0)); - mod_breadth = (float)((new_box.width * 1.0) / (box.width * 1.0)); - break; - - case GFX_BOX_SHADE_UP: - reverse = 1; - case GFX_BOX_SHADE_DOWN: - driver_shade_type = GFX_SHADE_VERTICALLY; - mod_offset = (float)(((new_box.y - box.y) * 1.0) / (box.height * 1.0)); - mod_breadth = (float)((new_box.height * 1.0) / (box.height * 1.0)); - break; - - default: - error("Invalid shade type: %d", shade_type); - } - - - if (reverse) - mod_offset = (float)(1.0 - (mod_offset + mod_breadth)); - // Reverse offset if we have to interpret colors inversely - - if (shade_type == GFX_BOX_SHADE_FLAT) { - color1.priority = 0; - color1.control = 0; - if (color1.visual.getParentIndex() == -1) - gfxop_set_color(state, &color1, color1); - drv->drawFilledRect(new_box, color1, color1, GFX_SHADE_FLAT); - return; - } -} - -void gfxop_fill_box(GfxState *state, rect_t box, gfx_color_t color) { - gfxop_draw_box(state, box, color, color, GFX_BOX_SHADE_FLAT); -} - -extern int sci0_palette; - -void gfxop_clear_box(GfxState *state, rect_t box) { - _gfxop_add_dirty(state, box); - DDIRTY(stderr, "[] clearing box %d %d %d %d\n", GFX_PRINT_RECT(box)); - - _gfxop_clip(&box, gfx_rect(0, 0, 320, 200)); -#ifdef PRECISE_PRIORITY_MAP - if (state->pic_unscaled) - gfx_copy_pixmap_box_i(state->priority_map, state->static_priority_map, box); -#endif - - _gfxop_scale_rect(&box, state->driver->getMode()); - - _gfxop_buffer_propagate_box(state, box, GFX_BUFFER_BACK); -} - -void gfxop_update(GfxState *state) { - _gfxop_clear_dirty_rec(state, state->_dirtyRects); - - if (state->tag_mode) { - // This usually happens after a pic and all resources have been drawn - state->gfxResMan->freeTaggedResources(); - state->tag_mode = 0; - } -} - -void gfxop_update_box(GfxState *state, rect_t box) { - if (state->disable_dirty) - _gfxop_update_box(state, box); - else - _gfxop_add_dirty(state, box); - - gfxop_update(state); -} - -void gfxop_enable_dirty_frames(GfxState *state) { - state->disable_dirty = 0; -} - -void gfxop_disable_dirty_frames(GfxState *state) { - state->disable_dirty = 1; -} - -// View operations - -void gfxop_get_cel_parameters(GfxState *state, int nr, int loop, int cel, int *width, int *height, Common::Point *offset) { - gfxr_view_t *view = NULL; - gfx_pixmap_t *pxm = NULL; - - view = state->gfxResMan->getView(nr, &loop, &cel, 0); - - if (!view) - error("[GFX] Attempt to get cel parameters for invalid view %d", nr); - - pxm = view->loops[loop].cels[cel]; - *width = pxm->index_width; - *height = pxm->index_height; - offset->x = pxm->xoffset; - offset->y = pxm->yoffset; -} - -static void _gfxop_draw_cel_buffer(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int static_buf, int palette) { - int priority = (color.mask & GFX_MASK_PRIORITY) ? color.priority : -1; - int control = (color.mask & GFX_MASK_CONTROL) ? color.control : -1; - gfxr_view_t *view = NULL; - gfx_pixmap_t *pxm = NULL; - int old_x, old_y; - - view = state->gfxResMan->getView(nr, &loop, &cel, palette); - - if (!view) { - warning("[GFX] Attempt to draw loop/cel %d/%d in invalid view %d\n", loop, cel, nr); - return; - } - pxm = view->loops[loop].cels[cel]; - - old_x = pos.x -= pxm->xoffset; - old_y = pos.y -= pxm->yoffset; - - pos.x *= state->driver->getMode()->scaleFactor; - pos.y *= state->driver->getMode()->scaleFactor; - - if (!static_buf) - _gfxop_add_dirty(state, gfx_rect(old_x, old_y, pxm->index_width, pxm->index_height)); - - _gfxop_draw_pixmap(state->driver, pxm, priority, control, gfx_rect(0, 0, pxm->width, pxm->height), - gfx_rect(pos.x, pos.y, pxm->width, pxm->height), state->clip_zone, static_buf , state->control_map, - static_buf ? state->static_priority_map : state->priority_map); -} - -void gfxop_draw_cel(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int palette) { - _gfxop_draw_cel_buffer(state, nr, loop, cel, pos, color, 0, palette); -} - -void gfxop_draw_cel_static(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int palette) { - rect_t oldclip = state->clip_zone; - - state->clip_zone = gfx_rect_fullscreen; - _gfxop_scale_rect(&(state->clip_zone), state->driver->getMode()); - gfxop_draw_cel_static_clipped(state, nr, loop, cel, pos, color, palette); - // Except that the area it's clipped against is... unusual ;-) - state->clip_zone = oldclip; -} - -void gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int palette) { - _gfxop_draw_cel_buffer(state, nr, loop, cel, pos, color, 1, palette); -} - -// Pic operations - -static void _gfxop_set_pic(GfxState *state) { - gfx_copy_pixmap_box_i(state->control_map, state->pic->control_map, gfx_rect(0, 0, 320, 200)); - gfx_copy_pixmap_box_i(state->priority_map, state->pic_unscaled->priority_map, gfx_rect(0, 0, 320, 200)); - gfx_copy_pixmap_box_i(state->static_priority_map, state->pic_unscaled->priority_map, gfx_rect(0, 0, 320, 200)); - - // Reset global palette to this PIC's palette - // 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 .) - if (state->pic->visual_map->palette) { - state->pic->visual_map->palette->forceInto(SCREEN_PALETTE); - _gfxop_install_pixmap(state->driver, state->pic->visual_map); - } - - state->driver->setStaticBuffer(state->pic->visual_map, state->pic->priority_map); -} - -void gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette) { - state->gfxResMan->tagResources(); - state->tag_mode = 1; - state->palette_nr = default_palette; - state->pic = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, true); - - if (state->driver->getMode()->scaleFactor == 1 && state->driver->getMode()->scaleFactor == 1) { - state->pic_unscaled = state->pic; - } else { - state->pic_unscaled = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false); - } - - if (!state->pic || !state->pic_unscaled) { - warning("Could not retrieve background pic %d", nr); - if (state->pic) { - warning(" -- Inconsistency: scaled pic _was_ retrieved!"); - } - - if (state->pic_unscaled) { - warning(" -- Inconsistency: unscaled pic _was_ retrieved!"); - } - - error("Error occured in gfxop_new_pic()"); - state->pic = state->pic_unscaled = NULL; - } - - state->pic_nr = nr; - - _gfxop_set_pic(state); -} - -void gfxop_add_to_pic(GfxState *state, int nr, int flags, int default_palette) { - if (!state->pic) - error("Attempt to add to pic with no pic active"); - - state->pic = state->gfxResMan->addToPic(state->pic_nr, nr, flags, state->palette_nr, default_palette); - - if (!state->pic) - error("Could not add pic #%d to pic #%d", state->pic_nr, nr); - - state->pic_unscaled = state->gfxResMan->addToPic(state->pic_nr, nr, flags, state->palette_nr, default_palette); - - _gfxop_set_pic(state); -} - -// Text operations - -void gfxop_get_text_params(GfxState *state, int font_nr, const char *text, int maxwidth, int *width, int *height, int text_flags, - int *lines_nr, int *lineheight, int *lastline_width) { - Common::Array<TextFragment> fragments; - bool textsplits; - gfx_bitmap_font_t *font; - - font = state->gfxResMan->getFont(font_nr); - - if (!font) - error("Attempt to calculate text size with invalid font #%d", font_nr); - - textsplits = gfxr_font_calculate_size(fragments, font, maxwidth, text, width, height, lineheight, lastline_width, text_flags); - - if (!textsplits) - error("Could not calculate text size"); - - if (lines_nr) - *lines_nr = fragments.size(); -} - -TextHandle *gfxop_new_text(GfxState *state, int font_nr, const Common::String &text, int maxwidth, gfx_alignment_t halign, - gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, gfx_color_t bg_color, int flags) { - TextHandle *handle; - gfx_bitmap_font_t *font; - - // mapping text colors to palette - gfxop_set_color(state, &color1, color1); - gfxop_set_color(state, &color2, color2); - gfxop_set_color(state, &bg_color, bg_color); - - font = state->gfxResMan->getFont(font_nr); - - if (!font) { - error("Attempt to draw text with invalid font #%d", font_nr); - return NULL; - } - - handle = new TextHandle(); - - handle->_text = text; - handle->halign = halign; - handle->valign = valign; - handle->line_height = font->line_height; - - bool result = gfxr_font_calculate_size(handle->lines, font, maxwidth, handle->_text.c_str(), &(handle->width), &(handle->height), - NULL, NULL, flags); - - if (!result) { - error("Could not calculate text parameters in font #%d", font_nr); - delete handle; - return NULL; - } - - if (flags & kFontNoNewlines) { - handle->lines.resize(1); - handle->lines[0].length = text.size(); - } - - handle->text_pixmaps.resize(handle->lines.size()); - - for (uint i = 0; i < handle->lines.size(); i++) { - int chars_nr = handle->lines[i].length; - - handle->text_pixmaps[i] = gfxr_draw_font(font, handle->lines[i].offset, chars_nr, - (color1.mask & GFX_MASK_VISUAL) ? &color1.visual : NULL, - (color2.mask & GFX_MASK_VISUAL) ? &color2.visual : NULL, - (bg_color.mask & GFX_MASK_VISUAL) ? &bg_color.visual : NULL); - - if (!handle->text_pixmaps[i]) { - error("Failed to draw text pixmap for line %d/%d", i, handle->lines.size()); - delete handle; - return NULL; - } - } - - handle->font = font; - - handle->priority = (color1.mask & GFX_MASK_PRIORITY) ? color1.priority : -1; - handle->control = (color1.mask & GFX_MASK_CONTROL) ? color1.control : -1; - - return handle; -} - -TextHandle::TextHandle() { - line_height = 0; - font = 0; - - width = height = 0; - - priority = control = 0; - halign = valign = ALIGN_BOTTOM; -} - -TextHandle::~TextHandle() { - for (uint j = 0; j < text_pixmaps.size(); j++) - if (text_pixmaps[j]) - gfx_free_pixmap(text_pixmaps[j]); -} - -void gfxop_draw_text(GfxState *state, TextHandle *handle, rect_t zone) { - int line_height; - rect_t pos; - - if (!handle) - error("Attempt to draw text with NULL handle"); - - if (handle->lines.empty()) { - debugC(2, kDebugLevelGraphics, "Skipping draw_text operation because number of lines is zero\n"); - return; - } - - _gfxop_scale_rect(&zone, state->driver->getMode()); - - line_height = handle->line_height * state->driver->getMode()->scaleFactor; - - pos.y = zone.y; - - switch (handle->valign) { - - case ALIGN_TOP: - break; - - case ALIGN_CENTER: - pos.y += (zone.height - (line_height * handle->lines.size())) >> 1; - break; - - case ALIGN_BOTTOM: - pos.y += (zone.height - (line_height * handle->lines.size())); - break; - - default: - error("Invalid vertical alignment %d", handle->valign); - } - - for (uint i = 0; i < handle->lines.size(); i++) { - - gfx_pixmap_t *pxm = handle->text_pixmaps[i]; - - if (!pxm->data) { - gfx_xlate_pixmap(pxm, state->driver->getMode()); - } - if (!pxm) - error("Could not find text pixmap %d/%d", i, handle->lines.size()); - - pos.x = zone.x; - - switch (handle->halign) { - - case ALIGN_LEFT: - break; - - case ALIGN_CENTER: - pos.x += (zone.width - pxm->width) >> 1; - break; - - case ALIGN_RIGHT: - pos.x += (zone.width - pxm->width); - break; - - default: - error("Invalid vertical alignment %d", handle->valign); - } - - pos.width = pxm->width; - pos.height = pxm->height; - - _gfxop_add_dirty(state, pos); - _gfxop_draw_pixmap(state->driver, pxm, handle->priority, handle->control, - gfx_rect(0, 0, pxm->width, pxm->height), pos, state->clip_zone, 0, state->control_map, state->priority_map); - - pos.y += line_height; - } -} - -gfx_pixmap_t *gfxop_grab_pixmap(GfxState *state, rect_t area) { - gfx_pixmap_t *pixmap = NULL; - rect_t resultzone; // Ignored for this application - - _gfxop_scale_rect(&area, state->driver->getMode()); - _gfxop_grab_pixmap(state, &pixmap, area.x, area.y, area.width, area.height, 0, &resultzone); - - return pixmap; -} - -void gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, Common::Point pos) { - rect_t target = gfx_rect(pos.x, pos.y, zone.width, zone.height); - - if (!pxm) - error("Attempt to draw NULL pixmap"); - - _gfxop_add_dirty(state, target); - - _gfxop_scale_rect(&zone, state->driver->getMode()); - _gfxop_scale_rect(&target, state->driver->getMode()); - - return _gfxop_draw_pixmap(state->driver, pxm, -1, -1, zone, target, gfx_rect(0, 0, 320*state->driver->getMode()->scaleFactor, - 200*state->driver->getMode()->scaleFactor), 0, NULL, NULL); -} - - - -#endif // INCLUDE_OLDGFX - -} // End of namespace Sci diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h deleted file mode 100644 index bc8b27b846..0000000000 --- a/engines/sci/gfx/operations.h +++ /dev/null @@ -1,530 +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. - * - * $URL$ - * $Id$ - * - */ - -/* Graphical operations, called from the widget state manager */ - -#ifndef SCI_GFX_GFX_OPERATIONS_H -#define SCI_GFX_GFX_OPERATIONS_H - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX -#include "sci/gfx/gfx_resmgr.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gfx/gfx_system.h" -#endif - -#include "common/list.h" - -namespace Sci { - -#ifdef INCLUDE_OLDGFX - -struct TextFragment; - -/* Threshold in color index mode to differentiate between visible and non-visible stuff. -** GFXOP_ALPHA_THRESHOLD itself should be treated as non-visible. -*/ -#define GFXOP_ALPHA_THRESHOLD 0xff - -struct TextHandle { - Common::String _text; /**< Copy of the actual text */ - - int line_height; - Common::Array<TextFragment> lines; /**< Text offsets */ - gfx_bitmap_font_t *font; - Common::Array<gfx_pixmap_t *> text_pixmaps; - - int width, height; - - int priority, control; - gfx_alignment_t halign, valign; - - TextHandle(); - ~TextHandle(); -}; - -/* Unless individually stated otherwise, the following applies: -** All operations herein apply to the standard 320x200 coordinate system. -** All operations perform clipping relative to state->clip_zone. -*/ - -enum gfx_box_shade_t { - GFX_BOX_SHADE_FLAT, - GFX_BOX_SHADE_RIGHT, - GFX_BOX_SHADE_LEFT, - GFX_BOX_SHADE_DOWN, - GFX_BOX_SHADE_UP -#if 0 - /* possible with alphaing, but there is no way to check for - ** alpha capability of gfx_driver->draw_filled_rect() yet - */ - , GFX_BOX_SHADE_RIGHT_DOWN, - GFX_BOX_SHADE_LEFT_DOWN, - GFX_BOX_SHADE_RIGHT_UP, - GFX_BOX_SHADE_LEFT_UP -#endif -}; - - -typedef Common::List<rect_t> DirtyRectList; - -#endif // INCLUDE_OLDGFX - -struct GfxState { -#ifdef INCLUDE_OLDGFX - rect_t clip_zone_unscaled; /**< The current UNSCALED clipping zone */ - rect_t clip_zone; /**< The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */ - - GfxDriver *driver; - - int visible_map; - - GfxResManager *gfxResMan; - - gfx_pixmap_t *priority_map; /**< back buffer priority map (unscaled) */ - gfx_pixmap_t *static_priority_map; /**< static buffer priority map (unscaled) */ - gfx_pixmap_t *control_map; /**< back buffer control map (only exists unscaled in the first place) */ - - - int tag_mode; /**< Set to 1 after a new pic is drawn and the resource manager has tagged all resources. Reset after the next front buffer update is done, when all resources that are still tagged are flushed. */ - - int disable_dirty; /**< Set to 1 to disable dirty rect accounting */ - - int pic_nr; /**< Number of the current pic */ - int palette_nr; /**< Palette number of the current pic */ - - gfxr_pic_t *pic, *pic_unscaled; /**< The background picture and its unscaled equivalent */ - rect_t pic_port_bounds; /**< Picture port bounds */ - - DirtyRectList _dirtyRects; /**< Dirty rectangles */ -#endif -}; - - -#ifdef INCLUDE_OLDGFX - - -/** @name Fundamental operations */ -/** @{ */ - -/** - * Initializes a graphics mode. - * - * @param[in] state The state to initialize - * @param[in] scaleFactor Scale factor - * @param[in] mode Graphics mode to use - * @param[in] resMan Resource manager to use - */ -void gfxop_init(GfxState *state, ResourceManager *resMan, - SciGuiScreen *screen, SciGuiPalette *palette, int scaleFactor = 1); - -/** - * Deinitializes a currently active driver. - * - * @param[in] state The state encapsulating the driver in question - */ -void gfxop_exit(GfxState *state); - -/** - * Calculates a bit mask calculated from some pixels on the specified - * map. - * - * @param[in] state The state containing the pixels to scan - * @param[in] area The area to check - * @param[in] map The GFX_MASKed map(s) to test - * @return An integer value where, for each 0 <= i <= 15, bit i is set - * iff there exists a map for which the corresponding bit was - * set in the 'map' parameter and for which there exists a - * pixel within the specified area so that the pixel's lower 4 - * bits, interpreted as an integer value, equal i. (Short - * version: This is an implementation of "on_control()"). - */ -int gfxop_scan_bitmask(GfxState *state, rect_t area, gfx_map_mask_t map); - -/** - * Sets a new clipping zone. - * - * @param[in] state The affected state - * @param[in] zone The new clipping zone - */ -void gfxop_set_clip_zone(GfxState *state, rect_t zone); -/** @} */ - - -/** @name Generic drawing operations */ -/** @{ */ - -/** - * Renders a clipped line to the back buffer. - * - * @param[in] state The state affected - * @param[in] start Starting point of the line - * @param[in] end End point of the line - * @param[in] color The color to use for drawing - * @param[in] line_mode Any valid line mode to use - * @param[in] line_style The line style to use - */ -void gfxop_draw_line(GfxState *state, - Common::Point start, Common::Point end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style); - -/** - * Draws a non-filled rectangular box to the back buffer. - * - * Boxes drawn in thin lines will surround the minimal area described by rect. - * - * @param[in] state The affected state - * @param[in] rect The rectangular area the box is drawn to - * @param[in] color The color the box is to be drawn in - * @param[in] line_mode The line mode to use - * @param[in] line_style The line style to use for the box - */ -void gfxop_draw_rectangle(GfxState *state, rect_t rect, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style); - -/** - * Draws a filled box to the back buffer. - * - * The draw mask, control, and priority values are derived from color1. - * - * @param[in] state The affected state - * @param[in] box The area to draw to - * @param[in] color1 The primary color to use for drawing - * @param[in] color2 The secondary color to draw in - * @param[in] shade_type The shading system to use (e.g. GFX_BOX_SHADE_FLAT) - */ -void gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, - gfx_color_t color2, gfx_box_shade_t shade_type); - -/** - * Fills a box in the back buffer with a specific color. - * - * This is a simple wrapper function for gfxop_draw_box - * - * @param[in] state The state to draw to - * @param[in] box The box to fill - * @param[in] color The color to use for filling - */ -void gfxop_fill_box(GfxState *state, rect_t box, gfx_color_t color); - -/** - * Copies a box from the static buffer to the back buffer. - * - * @param[in] state The affected state - * @param[in] box The box to propagate from the static buffer - */ -void gfxop_clear_box(GfxState *state, rect_t box); - - -/** - * Updates all dirty rectangles. - * - * In order to track dirty rectangles, they must be enabled in the options. This - * function instructs the resource manager to free all tagged data on certain - * occasions (see gfxop_new_pic). - * - * @param[in] state The relevant state - */ -void gfxop_update(GfxState *state); - - -/** - * Propagates a box from the back buffer to the front (visible) buffer. - * - * This function instructs the resource manager to free all tagged data on - * certain occasions (see gfxop_new_pic). When called with dirty rectangle - * management enabled, it will automatically propagate all dirty rectangles as - * well, UNLESS dirty frame accounting has been disabled explicitly. - * - * @param[in] state The affected state - * @param[in] box The box to propagate to the front buffer - */ -void gfxop_update_box(GfxState *state, rect_t box); - -/** - * Enables dirty frame accounting. - * - * Dirty frame accounting is enabled by default. - * - * @param[in] state The state dirty frame accounting is to be enabled in - */ -void gfxop_enable_dirty_frames(GfxState *state); - -/** - * Disables dirty frame accounting. - * - * @param[in] state The state dirty frame accounting is to be disabled in - */ -void gfxop_disable_dirty_frames(GfxState *state); -/** @} */ - - -/** @name Color operations */ -/** @{ */ - -/** - * Maps an r/g/b value to a color and sets a gfx_color_t structure. - * - * In palette mode, this may allocate a new color. If any of the r/g/b values - * are less than zero, the resulting color will not affect the visual map when - * used for drawing - * - * @param[in] state The current state - * @param[in] color Pointer to the structure to write to - * @param[in] r The red color intensity values of the result color - * @param[in] g The green color intensity values of the result color - * @param[in] b The blue color intensity values of the result color - * @param[in] a The alpha (transparency) value, with 0x00 meaning - * absolutely opaque and 0xff meaning fully transparent. - * Alpha blending support is optional for drivers, so these - * are the only two values that are guaranteed to work as - * intended. Any value in between them must guarantee the - * following opaqueness: opaqueness(x-1) >= opaqueness(x) - * >= opaqueness (x+1) (i.e. ([0,255], - * less-transparent-than) must define a partial order) - * @param[in] priority The priority to use for drawing, or -1 for none - * @param[in] control The control to use for drawing, or -1 to disable drawing - * to the control map - */ -void gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, - int a, int priority, int control); - -/** @} */ - -/** @name View operations */ -/** @{ */ - -/** - * Retrieves the width and height of a cel. - * - * @param[in] state The state to use - * @param[in] nr Number of the view - * @param[in] loop Loop number to examine - * @param[in] cel The cel (inside the loop) to look up - * @param[in] width The variable the width will be stored in - * @param[in] height The variable the height will be stored in - * @param[in] offset The variable the cel's x/y offset will be stored in - */ -void gfxop_get_cel_parameters(GfxState *state, int nr, int loop, int cel, - int *width, int *height, Common::Point *offset); - -/** - * Draws (part of) a cel to the back buffer. - * - * @param[in] state The state encapsulating the driver to draw with - * @param[in] nr Number of the view to draw - * @param[in] loop Loop of the cel to draw - * @param[in] cel The cel number of the cel to draw - * @param[in] pos The positino the cel is to be drawn to - * @param[in] color The priority and control values to use for drawing - * @param[in] palette The palette to use - */ -void gfxop_draw_cel(GfxState *state, int nr, int loop, int cel, - Common::Point pos, gfx_color_t color, int palette); - - -/** - * Draws a cel to the static buffer; no clipping is performed. - * - * No clipping (except for the display borders) is performed. - * - * @param[in] state The state encapsulating the driver to draw with - * @param[in] nr Number of the view to draw - * @param[in] loop Loop of the cel to draw - * @param[in] cel The cel number of the cel to draw - * @param[in] pos The positino the cel is to be drawn to - * @param[in] color The priority and control values to use for drawing - * @param[in] palette The palette to use - */ -void gfxop_draw_cel_static(GfxState *state, int nr, int loop, int cel, - Common::Point pos, gfx_color_t color, int palette); - - -/** - * Draws (part of) a clipped cel to the static buffer. - * - * This function does clip. - * - * @param[in] state The state encapsulating the driver to draw with - * @param[in] nr Number of the view to draw - * @param[in] loop Loop of the cel to draw - * @param[in] cel The cel number of the cel to draw - * @param[in] pos The positino the cel is to be drawn to - * @param[in] color The priority and control values to use for drawing - * @param[in] palette The palette to use - */ -void gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, - Common::Point pos, gfx_color_t color, int palette); -/** @} */ - - -/** @name Pic operations - * These operations are exempt from clipping */ -/** @{ */ - -/** - * Draws a pic and writes it over the static buffer. - * - * This function instructs the resource manager to tag all data as "unused". - * See the resource manager tag functions for a full description. - * - * @param[in] state The state affected - * @param[in] nr Number of the pic to draw - * @param[in] flags Interpreter-dependant flags to use for drawing - * @param[in] default_palette The default palette for drawing - */ -void gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette); - -/** - * Adds a pic to the static buffer. - * - * @param[in] state The state affected - * @param[in] nr Number of the pic to add - * @param[in] flags Interpreter-dependant flags to use for drawing - * @param[in] default_palette The default palette for drawing - */ -void gfxop_add_to_pic(GfxState *state, int nr, int flags, int default_palette); -/** @} */ - - -/** @name Text operations */ - -/** - * Calculates the width and height of a specified text in a specified - * font. - * - * @param[in] state The state to use - * @param[in] font_nr Font number to use for the calculation - * @param[in] text The text to examine - * @param[in] flags ORred GFXR_FONT_FLAGs - * @param[in] maxwidth The maximum pixel width to allow for the text - * @param[out] width The resulting width - * @param[out] height The resulting height - * @param[out] lines_nr Number of lines used in the text - * @param[out] lineheight Pixel height (SCI scale) of each text line - * @param[out] lastline_width Pixel offset (SCI scale) of the space after - * the last character in the last line - */ -void gfxop_get_text_params(GfxState *state, int font_nr, const char *text, - int maxwidth, int *width, int *height, int flags, - int *lines_nr, int *lineheight, int *lastline_width); - -/** - * Generates a new text handle that can be used to draw any text. - * - * The control and priority values for the text will be extracted from color1. - * Note that the colors must have been allocated properly, or the text may - * display in incorrect colors. - * - * @param[in] state The state to use - * @param[in] font_nr Font number to use for the calculation - * @param[in] text The text to examine - * @param[in] maxwidth: The maximum pixel width to allow for the text - * @param[in] halign The horizontal text alignment - * @param[in] valign The vertical text alignment - * @param[in] color1 The text's foreground colors (the function will dither - * between color1 and 2) - * @param[in] color2 The text's foreground colors (the function will dither - * between color1 and 2) - * @param[in] bg_color The background color - * @param[in] flags ORred GFXR_FONT_FLAGs - * @return A newly allocated TextHandle, or NULL if font_nr was - * invalid - */ -TextHandle *gfxop_new_text(GfxState *state, int font_nr, - const Common::String &text, int maxwidth, gfx_alignment_t halign, - gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, - gfx_color_t bg_color, int flags); - -/** - * Draws text stored in a text handle. - * - * @param[in] state The target state - * @param[in] handle The text handle to use for drawing - * @param[in] zone The rectangular box to draw to. In combination with - * halign and valign, this defines where the text is drawn - * to. - */ -void gfxop_draw_text(GfxState *state, TextHandle *handle, rect_t zone); -/** @} */ - - -/** @name Manual pixmap operations */ -/** @{ */ - -/** - * Grabs a screen section from the back buffer and stores it in a pixmap. - * - * Obviously, this only affects the visual map - * - * @param[in] state The affected state - * @param[in] area The area to grab - * Returns A result pixmap, or NULL on error - */ -gfx_pixmap_t *gfxop_grab_pixmap(GfxState *state, rect_t area); - -/** - * Draws part of a pixmap to the screen. - * - * @param[in] state The affected state - * @param[in] pxm The pixmap to draw - * @param[in] zone The segment of the pixmap to draw - * @param[in] pos The position the pixmap should be drawn to - */ -void gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, - Common::Point pos); - -/** @} */ - - -/** @name Dirty rectangle operations */ -/** @{ */ - -/** - * Adds a dirty rectangle to 'base' according to a strategy. - * - * @param[in] list the list to add to - * @param[in] box the dirty frame to addable - */ -void gfxdr_add_dirty(DirtyRectList &list, rect_t box); - -/** - * Clips a rectangle against another one. - * - * @param[in] rect The rectangle to clip - * @param[in] clipzone The outer bounds rect must be in - * @return 1 if rect is empty now, 0 otherwise - */ -int _gfxop_clip(rect_t *rect, rect_t clipzone); -/** @} */ - -#endif // INCLUDE_OLDGFX - -/** @name Pointer and IO ops */ -/** @{ */ - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_OPERATIONS_H diff --git a/engines/sci/gfx/palette.cpp b/engines/sci/gfx/palette.cpp deleted file mode 100644 index 62e70e2a6d..0000000000 --- a/engines/sci/gfx/palette.cpp +++ /dev/null @@ -1,330 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/palette.h" -#include "sci/gfx/gfx_system.h" - -// #define DEBUG_MERGE - -namespace Sci { - -Palette::Palette(uint s) { - _size = s; - _colors = new PaletteEntry[s]; - _parent = 0; - _dirty = true; - _refcount = 1; - _revision = 0; -} - -Palette::Palette(const PaletteEntry *colors, uint s) { - _size = s; - _colors = new PaletteEntry[s]; - _parent = 0; - _dirty = true; - _refcount = 1; - _revision = 0; - - for (uint i = 0; i < _size; ++i) { - _colors[i].r = colors[i].r; - _colors[i].g = colors[i].g; - _colors[i].b = colors[i].b; - _colors[i].refcount = 0; - _colors[i]._parentIndex = -1; - } -} - -Palette::~Palette() { - if (_parent) - unmerge(); - - delete[] _colors; - _colors = 0; -} - -Palette *Palette::getref() { - _refcount++; - return this; -} - -void Palette::free() { - assert(_refcount > 0); - _refcount--; - - if (_refcount == 0) - delete this; -} - -void Palette::resize(uint s) { - if (s == _size) - return; - - assert(!_parent); - assert(_refcount == 1); - assert(s >= _size); - - PaletteEntry *n = new PaletteEntry[s]; - for (uint i = 0; i < _size; ++i) - n[i] = _colors[i]; - - delete[] _colors; - _colors = n; - _size = s; -} - -void Palette::unmerge() { - assert(_parent); -#ifdef DEBUG_MERGE - fprintf(stderr, "Unmerge %s from %s (%d colors)\n", name.c_str(), _parent->name.c_str(), _size); -#endif - if (_parent->_revision != _revision) { -#ifdef DEBUG_MERGE - fprintf(stderr, "NOP (revision mismatch)\n"); -#endif - return; - } - - int count = 0; - for (uint i = 0; i < _size; ++i) { - if (_colors[i].refcount == PaletteEntry::FREE) { - assert(_colors[i]._parentIndex == 0); - } - - int pi = _colors[i]._parentIndex; - assert(pi >= 0); - assert(pi < (int)_parent->_size); - assert(_parent->_colors[pi].refcount != 0); - assert(_parent->_colors[pi].refcount != PaletteEntry::FREE); - if (_parent->_colors[pi].refcount != PaletteEntry::LOCKED) - _parent->_colors[pi].refcount--; - if (_parent->_colors[pi].refcount == 0) { - _parent->_colors[pi].refcount = PaletteEntry::FREE; - count++; - } - _colors[i]._parentIndex = -1; - } -#ifdef DEBUG_MERGE - fprintf(stderr, "Unmerge free %d colors\n", count); -#endif - - _parent = 0; -} - -void Palette::setColor(uint index, byte r, byte g, byte b, int parentIndex) { - assert(index < _size); - assert(!_parent); - -// FIXME: We may want to have this assert. This will require changing the -// way loops sharing a single view's palette works. -// assert(_refcount == 1); - - PaletteEntry& entry = _colors[index]; - - assert(entry.refcount == PaletteEntry::FREE || entry.refcount == 0); - entry.refcount = 0; - entry.r = r; - entry.g = g; - entry.b = b; - entry._parentIndex = parentIndex; - - _dirty = true; -} - -void Palette::makeSystemColor(uint index, const PaletteEntry &color) { - assert(index < _size); - PaletteEntry& entry = _colors[index]; - entry.r = color.r; - entry.g = color.g; - entry.b = color.b; - entry.refcount = PaletteEntry::LOCKED; -} - -uint Palette::findNearbyColor(byte r, byte g, byte b, bool lock) { - int bestdelta = 1 + ((0x100 * 0x100) * 3); - int bestcolor = -1; - int firstfree = -1; - - assert(_size != 0); - - for (uint i = 0; i < _size; ++i) { - PaletteEntry& entry = _colors[i]; - - if (entry.refcount != PaletteEntry::FREE) { - int dr = abs(entry.r - r); - int dg = abs(entry.g - g); - int db = abs(entry.b - b); - - if (dr == 0 && dg == 0 && db == 0) { - // Exact match - //exact = true; - if (lock && entry.refcount != PaletteEntry::LOCKED) - entry.refcount++; - return i; - } - - int delta = (dr * dr) + (dg * dg) + (db * db); - if (delta < bestdelta) { - bestdelta = delta; - bestcolor = i; - } - } else { - if (firstfree == -1) - firstfree = i; - } - } - - if (firstfree != -1) { - // TODO: mark palette as dirty - setColor(firstfree, r, g, b); - //exact = true; - if (lock) - _colors[firstfree].refcount++; - return firstfree; - } - - //exact = false; - if (lock && _colors[bestcolor].refcount != PaletteEntry::LOCKED) { -#if 0 - _colors[bestcolor].r = r; - _colors[bestcolor].g = g; - _colors[bestcolor].b = b; - _dirty = true; -#endif - _colors[bestcolor].refcount++; - } - return bestcolor; -} - -bool Palette::mergeInto(Palette *parent) { - assert(!_parent || _parent == parent); - assert(parent != this); -#ifdef DEBUG_MERGE - fprintf(stderr, "Merge: %s into %s (%d colors)\n", name.c_str(), parent->name.c_str(), _size); -#endif - - if (_parent == parent && parent->_revision == _revision) { -#ifdef DEBUG_MERGE - fprintf(stderr, "NOP\n"); -#endif - return false; - } - _parent = parent; - _revision = parent->_revision; - -#ifdef DEBUG_MERGE - bool *used = new bool[_parent->size()]; - for (uint i = 0; i < _parent->size(); ++i) - used[i] = false; - int count = 0; - uint used_min = 1000; - uint used_max = 0; -#endif - - for (uint i = 0; i < _size; ++i) { - PaletteEntry& entry = _colors[i]; - if (entry.refcount == PaletteEntry::FREE) { - // Force all unused colours to index 0 - entry._parentIndex = 0; - if (_parent->_colors[0].refcount != PaletteEntry::LOCKED) - _parent->_colors[0].refcount++; - if (_colors[i].r || _colors[i].g || _colors[i].b) - warning("Non-black unused colour in pic: index %d, %02X %02X %02X", i, _colors[i].r, _colors[i].g, _colors[i].b); - continue; - } - - uint pi = _parent->findNearbyColor(entry.r, entry.g, entry.b); -#ifdef DEBUG_MERGE - if (!used[pi]) count++; - used[pi] = true; - if (pi > used_max) used_max = pi; - if (pi < used_min) used_min = pi; -#endif - entry._parentIndex = pi; - if (_parent->_colors[pi].refcount != PaletteEntry::LOCKED) - _parent->_colors[pi].refcount++; - } -#ifdef DEBUG_MERGE - fprintf(stderr, "Merge used %d colours in [%d..%d]\n", count, used_min, used_max); - delete[] used; -#endif - return true; -} - -void Palette::forceInto(Palette *parent) { - assert(!_parent || _parent == parent); - assert(parent != this); -#ifdef DEBUG_MERGE - fprintf(stderr, "Merge: force %s into %s (%d colors)\n", name.c_str(), parent->name.c_str(), _size); -#endif - - _parent = parent; - parent->_revision++; - _revision = parent->_revision; - - for (unsigned int i = 0; i < _size; ++i) { - // FIXME: PaletteEntry::LOCKED doesn't work well with forceInto... - if (_colors[i].refcount != PaletteEntry::FREE) { - _parent->_colors[i] = _colors[i]; - _parent->_colors[i]._parentIndex = -1; - _colors[i]._parentIndex = i; - if (_parent->_colors[i].refcount != PaletteEntry::LOCKED) - _parent->_colors[i].refcount = 1; - } else { - _parent->_colors[i].refcount = 0; - // Force all unused colours to index 0 - _colors[i]._parentIndex = 0; - if (_parent->_colors[0].refcount != PaletteEntry::LOCKED) { - if (i == 0) - _parent->_colors[0].refcount = 1; - else - _parent->_colors[0].refcount++; - } - if (_colors[i].r || _colors[i].g || _colors[i].b) - warning("Non-black unused colour in pic: index %d, %02X %02X %02X", i, _colors[i].r, _colors[i].g, _colors[i].b); - } - } - _parent->_dirty = true; -} - -Palette *Palette::copy() { - assert(!_parent); - Palette* p = new Palette(_size); - p->name = "copy of " + name; - - for (uint i = 0; i < _size; ++i) { - p->_colors[i] = _colors[i]; - if (p->_colors[i].refcount >= 0) - p->_colors[i].refcount = 0; - } - return p; -} - - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/palette.h b/engines/sci/gfx/palette.h deleted file mode 100644 index b74eebd72e..0000000000 --- a/engines/sci/gfx/palette.h +++ /dev/null @@ -1,129 +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. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_PALETTE_H -#define SCI_GFX_PALETTE_H - -#include "common/scummsys.h" -#include "common/str.h" - -namespace Sci { - -class PaletteEntry { - - friend class Palette; - - enum { - LOCKED = -42, - FREE = -41 - }; - -public: - PaletteEntry() - : r(0), g(0), b(0), _parentIndex(-1), refcount(FREE) - { } - PaletteEntry(byte R, byte G, byte B) - : r(R), g(G), b(B), _parentIndex(-1), refcount(FREE) - { } - - /** @name Color data */ - /** @{ */ - byte r, g, b; - /** @} */ - - inline int getParentIndex() const { return _parentIndex; } - - /** Index in parent palette, or -1 */ - int _parentIndex; - -protected: - /** - * Number of references from child palettes. (This includes palettes - * of pixmaps.) - * Special values: PALENTRY_LOCKED, PALENTRY_FREE */ - int refcount; -}; - -class Palette { -public: - explicit Palette(uint size); - Palette(const PaletteEntry *colors, uint size); - ~Palette(); - - Palette *getref(); - void free(); - Palette *copy(); - - void resize(uint size); - void setColor(uint index, byte r, byte g, byte b, int parentIndex = -1); - void makeSystemColor(uint index, const PaletteEntry &color); - const PaletteEntry &getColor(uint index) const { - assert(index < _size); - return _colors[index]; - } - const PaletteEntry &operator[](uint index) const { - return getColor(index); - } - uint size() const { return _size; } - bool isDirty() const { return _dirty; } - bool isShared() const { return _refcount > 1; } - Palette *getParent() { return _parent; } - int getRevision() const { return _revision; } - - void markClean() { _dirty = false; } - - uint findNearbyColor(byte r, byte g, byte b, bool lock=false); - - bool mergeInto(Palette *parent); // returns false if already merged - void forceInto(Palette *parent); - - void unmerge(); - - Common::String name; // strictly for debugging purposes -private: - PaletteEntry *_colors; - uint _size; - - Palette *_parent; - - /** Palette has changed */ - bool _dirty; - - /** Number of pixmaps (or other objects) using this palette */ - int _refcount; - - /** When this is incremented, all child references are invalidated */ - int _revision; -}; - - -} // End of namespace Sci - -#endif // SCI_GFX_PALETTE_H - -#endif |