aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/gui32/picfill.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/gui32/picfill.cpp')
-rw-r--r--engines/sci/gui32/picfill.cpp588
1 files changed, 0 insertions, 588 deletions
diff --git a/engines/sci/gui32/picfill.cpp b/engines/sci/gui32/picfill.cpp
deleted file mode 100644
index f48f7e938d..0000000000
--- a/engines/sci/gui32/picfill.cpp
+++ /dev/null
@@ -1,588 +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/gfx/gfx_resource.h"
-
-/* Generic pic filling code, to be included by sci_pic_0.c
- *
- *
- * To use, define the following:
- * AUXBUF_FILL: Name of the exported floodfill function
- * AUXBUF_FILL_HELPER: Name of the helper function
- * FILL_FUNCTION: Name of the exported floodfill function
- * FILL_FUNCTION_RECURSIVE: Name of the helper function
- *
- * Define DRAW_SCALED to support scaled drawing, or leave it out for faster
- * processing.
- *
- */
-
-namespace Sci {
-
-#define CLIPMASK_HARD_BOUND 0x80 /* ensures that we don't re-fill filled stuff */
-
-static void AUXBUF_FILL_HELPER(gfxr_pic_t *pic, int old_xl, int old_xr, int y, int dy,
- int clipmask, int control, int sci_titlebar_size) {
- int xl, xr;
- int oldytotal = y * 320;
-#ifdef DRAW_SCALED
- unsigned const char fillmask = CLIPMASK_HARD_BOUND | 0x78;
-#else
- unsigned const char fillmask = CLIPMASK_HARD_BOUND | 0x84;
-#endif
-
- do {
- int ytotal = oldytotal + (320 * dy);
- int xcont;
- int state;
-
- y += dy;
-
- if (y < sci_titlebar_size || y > 199)
- return;
-
- xl = old_xl;
- if (!(pic->aux_map[ytotal + xl] & clipmask)) { // go left
- while (xl && !(pic->aux_map[ytotal + xl - 1] & clipmask))
- --xl;
- } else // go right and look for the first valid spot
- while ((xl <= old_xr) && (pic->aux_map[ytotal + xl] & clipmask))
- ++xl;
-
- if (xl > old_xr) // No fillable strip above the last one
- return;
-
- assert((ytotal + xl) >= 0);
-
- xr = xl;
- while (xr < 320 && !(pic->aux_map[ytotal + xr] & clipmask)) {
- pic->aux_map[ytotal + xr] |= fillmask;
- ++xr;
- }
-
- assert((ytotal + xr) <= 64000);
-
- --xr;
-
- if (xr < xl)
- return;
-
- // Check whether we need to recurse on branches in the same direction
- if ((y > sci_titlebar_size && dy < 0) || (y < 199 && dy > 0)) {
- state = 0;
- xcont = xr + 1;
- while (xcont <= old_xr) {
- if (pic->aux_map[ytotal + xcont] & clipmask)
- state = 0;
- else if (!state) { // recurse
- state = 1;
- AUXBUF_FILL_HELPER(pic, xcont, old_xr, y - dy, dy, clipmask, control, sci_titlebar_size);
- }
- ++xcont;
- }
- }
-
- // Check whether we need to recurse on backward branches:
- // left
- if (xl < old_xl - 1) {
- state = 0;
- for (xcont = old_xl - 1; xcont >= xl; xcont--) {
- if (pic->aux_map[oldytotal + xcont] & clipmask)
- state = xcont;
- else if (state) { // recurse
- AUXBUF_FILL_HELPER(pic, xcont, state, y, -dy, clipmask, control, sci_titlebar_size);
- state = 0;
- }
- }
- }
-
- // right
- if (xr > old_xr + 1) {
- state = 0;
- for (xcont = old_xr + 1; xcont <= xr; xcont++) {
- if (pic->aux_map[oldytotal + xcont] & clipmask)
- state = xcont;
- else if (state) { // recurse
- AUXBUF_FILL_HELPER(pic, state, xcont, y, -dy, clipmask, control, sci_titlebar_size);
- state = 0;
- }
- }
- }
-
- assert((ytotal + xl) >= 0);
- assert((ytotal + xr + 1) <= 64000);
-
- if (control)
- memset(pic->control_map->index_data + ytotal + xl, control, xr - xl + 1);
-
- oldytotal = ytotal;
- old_xr = xr;
- old_xl = xl;
-
- } while (1);
-}
-
-
-static void AUXBUF_FILL(gfxr_pic_t *pic, int x, int y, int clipmask, int control, int sci_titlebar_size) {
- // Fills the aux buffer and the control map (if control != 0)
- int xl, xr;
- int ytotal = y * 320;
-#ifdef DRAW_SCALED
- unsigned const char fillmask = 0x78;
-#else
- unsigned const char fillmask = 0x4;
-#endif
-
-#ifndef DRAW_SCALED
- if (!control || !(clipmask & 4))
- return; // Without pic scaling, we only do this to fill the control map
-#endif
-
- if (clipmask & 1)
- clipmask = 1; // vis
- else if (clipmask & 2)
- clipmask = 2; // pri
- else if (clipmask & 4)
- clipmask = 4; // ctl
- else return;
-
-#ifdef DRAW_SCALED
- clipmask |= fillmask; // Bits 3-5
-#endif
-
- if (pic->aux_map[ytotal + x] & clipmask)
- return;
-
- pic->aux_map[ytotal + x] |= fillmask;
-
- xl = x;
- while (xl && !(pic->aux_map[ytotal + xl - 1] & clipmask)) {
- --xl;
- pic->aux_map[ytotal + xl] |= fillmask;
- }
-
- xr = x;
- while ((xr < 319) && !(pic->aux_map[ytotal + xr + 1] & clipmask)) {
- ++xr;
- pic->aux_map[ytotal + xr] |= fillmask;
- }
-
- clipmask |= CLIPMASK_HARD_BOUND; // Guarantee clipping
-
- if (control) // Draw the same strip on the control map
- memset(pic->control_map->index_data + ytotal + xl, control, xr - xl + 1);
-
- if (y > sci_titlebar_size)
- AUXBUF_FILL_HELPER(pic, xl, xr, y, -1, clipmask, control, sci_titlebar_size);
-
- if (y < 199)
- AUXBUF_FILL_HELPER(pic, xl, xr, y, + 1, clipmask, control, sci_titlebar_size);
-}
-
-
-#undef CLIPMASK_HARD_BOUND
-
-
-#ifdef FILL_RECURSIVE_DEBUG
-# define PRINT_DEBUG0(s) if (!fillmagc) fprintf(stderr, s)
-# define PRINT_DEBUG1(s,p1) if (!fillmagc) fprintf(stderr, s, p1)
-# define PRINT_DEBUG4(s,p1,p2,p3,p4) if (!fillmagc) fprintf(stderr, s, p1)
-#else
-# define PRINT_DEBUG0(s)
-# define PRINT_DEBUG1(s,p1)
-# define PRINT_DEBUG4(s,p1,p2,p3,p4)
-#endif
-
-#ifdef DRAW_SCALED
-# define SCALED_CHECK(x) (x)
-# define IS_BOUNDARY(x, y, index) (((index) & legalmask) != legalcolor)
-#else
-# define SCALED_CHECK(x) 1
-# define IS_BOUNDARY(x, y, index) ( \
- (((x)+(y)) & 1)? /* figure out which part of the mask to use, to simulate dithering */ \
- ((((index)) & ((legalmask) )) != ((legalcolor) & ((legalmask)))) /* odd coordinate */ \
- : ((((index)) & ((legalmask) >> 8)) != ((legalcolor) & ((legalmask) >> 8))) /* even coordinate */ \
- )
-#endif
-
-static void FILL_FUNCTION_RECURSIVE(gfxr_pic_t *pic, int old_xl, int old_xr, int y, int dy, byte *bounds,
- int legalcolor, int legalmask, int color, int priority, int drawenable, int sci_titlebar_size) {
- int linewidth = pic->mode->scaleFactor * 320;
- int miny = pic->mode->scaleFactor * sci_titlebar_size;
- int maxy = pic->mode->scaleFactor * 200;
- int xl, xr;
- int oldytotal = y * linewidth;
-#ifdef DRAW_SCALED
- int old_proj_y = -42;
- int proj_y;
- int proj_ytotal;
- int proj_x;
- int proj_xl_bound = 0;
- int proj_xr_bound = 0;
-#endif
-
- do {
- int ytotal = oldytotal + (linewidth * dy);
- int xcont;
- int state;
-
- y += dy;
-
-#ifdef FILL_RECURSIVE_DEBUG
- if (!fillc)
- return;
- else if (!fillmagc) {
- --fillc;
- }
-#endif
-
- if (y < miny || y >= maxy) {
- PRINT_DEBUG0("ABRT on failed initial assertion!\n");
- return;
- }
-#ifdef DRAW_SCALED
- proj_y = y / pic->mode->yfact;
-
- if (proj_y != old_proj_y) {
- // First, find the projected coordinates, unless known already:
- proj_ytotal = proj_y * 320;
- proj_x = old_xl / pic->mode->xfact;
-
- proj_xl_bound = proj_x;
- if (SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) {
- while (proj_xl_bound && pic->aux_map[proj_ytotal + proj_xl_bound - 1] & FRESH_PAINT)
- --proj_xl_bound;
- } else {
- while (proj_xl_bound < 319 && !(pic->aux_map[proj_ytotal + proj_xl_bound + 1] & FRESH_PAINT))
- ++proj_xl_bound;
-
- if (proj_xl_bound < 319)
- ++proj_xl_bound;
- }
-
- if (proj_xl_bound == 319
- && !(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) {
- PRINT_DEBUG0("ABRT because proj_xl_bound couldn't be found\n");
- return;
- }
-
- proj_xr_bound = (proj_xl_bound > proj_x) ? proj_xl_bound : proj_x;
- while ((proj_xr_bound < 319)
- && pic->aux_map[proj_ytotal + proj_xr_bound + 1] & FRESH_PAINT)
- ++proj_xr_bound;
-
-#ifdef FILL_RECURSIVE_DEBUG
- if (!fillmagc) {
- fprintf(stderr, "l%d: {%d,%d} | ", proj_y, proj_xl_bound, proj_xr_bound);
- pic->aux_map[proj_y*320 + proj_xl_bound] |= 0x2;
- pic->aux_map[proj_y*320 + proj_xr_bound] |= 0x2;
- }
-#endif
-
- proj_xl_bound *= pic->mode->xfact;
- if (proj_xl_bound)
- proj_xl_bound -= pic->mode->xfact - 1;
-
- if (proj_xr_bound < 319)
- ++proj_xr_bound;
- proj_xr_bound *= pic->mode->xfact;
- proj_xr_bound += pic->mode->xfact - 1;
-
- old_proj_y = proj_y;
- }
-#else
-# define proj_xl_bound 0
-# define proj_xr_bound 319
-#endif
-
- // Now we have the projected limits, get the real ones:
-
- xl = (old_xl > proj_xl_bound) ? old_xl : proj_xl_bound;
- if (!IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl])) { // go left as far as possible
- while (xl > proj_xl_bound && (!IS_BOUNDARY(xl - 1, y + 1, bounds[ytotal + xl - 1])))
- --xl;
- } else // go right until the fillable area starts
- while (xl < proj_xr_bound && (IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl])))
- ++xl;
-
-
- PRINT_DEBUG1("<%d,", xl);
-
- if ((xl > proj_xr_bound)
- || (xl > old_xr)) {
- PRINT_DEBUG0("ABRT because xl > xr_bound\n");
- return;
- }
-
- xr = (xl > old_xl) ? xl : old_xl;
- while (xr < proj_xr_bound && (!IS_BOUNDARY(xr + 1, y + 1, bounds[ytotal + xr + 1])))
- ++xr;
-
- PRINT_DEBUG1("%d> -> ", xr);
-
- if (IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl])) {
- PRINT_DEBUG0("ABRT because xl illegal\n");
- return;
- }
-
-#ifdef DRAW_SCALED
- PRINT_DEBUG4("[%d[%d,%d]%d]\n", proj_xl_bound, xl, xr, proj_xr_bound);
-
- if (xl < proj_xl_bound && xr - 3*pic->mode->xfact < proj_xl_bound) {
- PRINT_DEBUG0("ABRT interval left of zone\n");
- return;
- }
-
- if (xr > proj_xr_bound && xl + 3*pic->mode->xfact > proj_xr_bound) {
- PRINT_DEBUG0("ABRT because interval right of zone\n");
- return;
- }
-#endif
-
- if (drawenable & GFX_MASK_VISUAL)
- memset(pic->visual_map->index_data + ytotal + xl, color, xr - xl + 1);
-
- if (drawenable & GFX_MASK_PRIORITY)
- memset(pic->priority_map->index_data + ytotal + xl, priority, xr - xl + 1);
-
-
- // Check whether we need to recurse on branches in the same direction
- state = 0;
- xcont = xr + 1;
- while (xcont <= old_xr) {
- if (IS_BOUNDARY(xcont, y + 1, bounds[ytotal + xcont]))
- state = xcont;
- else if (state) { // recurse
- PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr);
- PRINT_DEBUG4("rec BRANCH %d [%d,%d] l%d\n", dy, state, xcont, y - dy);
-
- FILL_FUNCTION_RECURSIVE(pic, state, xcont, y - dy, dy, bounds, legalcolor,
- legalmask, color, priority, drawenable, sci_titlebar_size);
- state = 0;
- }
- ++xcont;
- }
-
- // Check whether we need to recurse on backward branches:
- // left
- if (xl < old_xl - 1) {
- state = 0;
- for (xcont = old_xl - 1; xcont >= xl; xcont--) {
- if (IS_BOUNDARY(xcont, y, bounds[oldytotal + xcont]))
- state = xcont;
- else if (state) { // recurse
- PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr);
- PRINT_DEBUG4("rec BACK-LEFT %d [%d,%d] l%d\n", -dy, state, xcont, y);
-
- FILL_FUNCTION_RECURSIVE(pic, xcont, state, y, -dy, bounds,
- legalcolor, legalmask, color, priority, drawenable,
- sci_titlebar_size);
- state = 0;
- }
- }
- }
-
- // right
- if (xr > old_xr + 1) {
- state = 0;
- for (xcont = old_xr + 1; xcont <= xr; xcont++) {
- if (IS_BOUNDARY(xcont, y, bounds[oldytotal + xcont]))
- state = xcont;
- else if (state) { // recurse
- PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr);
- PRINT_DEBUG4("rec BACK-RIGHT %d [%d,%d] l%d\n", -dy, state, xcont, y);
-
- FILL_FUNCTION_RECURSIVE(pic, state, xcont, y, -dy, bounds,
- legalcolor, legalmask, color, priority, drawenable,
- sci_titlebar_size);
- state = 0;
- }
- }
- }
-
- oldytotal = ytotal;
- old_xl = xl;
- old_xr = xr;
-
- } while (1);
-}
-
-
-static void FILL_FUNCTION(gfxr_pic_t *pic, int x_320, int y_200, int color, int priority, int control, int drawenable,
- int sci_titlebar_size) {
- int linewidth = pic->mode->scaleFactor * 320;
- int x, y;
- int xl, xr;
- int ytotal;
- int bitmask;
- byte *bounds = NULL;
- int legalcolor, legalmask;
-#ifdef DRAW_SCALED
- int min_x, min_y, max_x, max_y;
-#endif
- int original_drawenable = drawenable; // Backup, since we need the unmodified value
- // for filling the aux and control map
-
- // Restrict drawenable not to restrict itself to zero
- if (pic->control_map->index_data[y_200 * 320 + x_320] != 0)
- drawenable &= ~GFX_MASK_CONTROL;
-
- if (color == 0xff)
- drawenable &= ~GFX_MASK_VISUAL;
-
- if (priority == 0) {
- drawenable &= ~GFX_MASK_PRIORITY;
- original_drawenable &= ~GFX_MASK_PRIORITY;
- }
-
- AUXBUF_FILL(pic, x_320, y_200, original_drawenable, (drawenable & GFX_MASK_CONTROL) ? control : 0,
- sci_titlebar_size);
-
-#ifdef DRAW_SCALED
- _gfxr_auxbuf_spread(pic, &min_x, &min_y, &max_x, &max_y);
-
- if (_gfxr_find_fill_point(pic, min_x, min_y, max_x, max_y, x_320, y_200, color, drawenable, &x, &y)) {
- //GFXWARN("Could not find scaled fill point, but unscaled fill point was available!\n");
- drawenable &= GFX_MASK_PRIORITY;
- if (!drawenable)
- _gfxr_auxbuf_propagate_changes(pic, 0);
- }
-#else
- x = x_320;
- y = y_200;
-#endif
-
- ytotal = y * linewidth;
-
- if (!drawenable)
- return;
-
- if (drawenable & GFX_MASK_VISUAL) {
- bounds = pic->visual_map->index_data;
-#if 0
- // Code disabled, as removing it fixes qg1 pic.095 (unscaled). However,
- // it MAY be of relevance to scaled pic drawing...
-
- if ((color & 0xf) == 0xf // When dithering with white, do more
- // conservative checks
- || (color & 0xf0) == 0xf0)
- legalcolor = 0xff;
- else
- legalcolor = 0xf0; // Only check the second color
-#endif
-#ifdef DRAW_SCALED
- legalcolor = 0xff;
- legalmask = legalcolor;
-#else
- legalmask = 0x0ff0;
- legalcolor = 0xff;
-#endif
- } else if (drawenable & GFX_MASK_PRIORITY) {
- bounds = pic->priority_map->index_data;
- legalcolor = 0;
- legalmask = 0x0f0f;
- } else {
- legalcolor = 0;
- legalmask = 0x0f0f;
- }
-
- if (!bounds || IS_BOUNDARY(x, y, bounds[ytotal + x]))
- return;
-
- if (bounds) {
-#ifdef DRAW_SCALED
- int proj_y = y_200;
- int proj_ytotal = proj_y * 320;
- int proj_x = x_320;
- int proj_xl_bound;
- int proj_xr_bound;
- int proj_xl, proj_xr;
-
- ytotal = y * linewidth;
-
- proj_xl_bound = proj_x;
- if (SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) {
- while (proj_xl_bound && SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound - 1] & FRESH_PAINT))
- --proj_xl_bound;
- } else
- while (proj_xl_bound < 319 && SCALED_CHECK(!(pic->aux_map[proj_ytotal + proj_xl_bound + 1] & FRESH_PAINT)))
- ++proj_xl_bound;
-
- proj_xr_bound = (proj_xl_bound > proj_x) ? proj_xl_bound : proj_x;
- while ((proj_xr_bound < 319) && SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xr_bound + 1] & FRESH_PAINT))
- ++proj_xr_bound;
-
- proj_xl = proj_xl_bound;
- proj_xr = proj_xr_bound;
-
- proj_xl_bound *= pic->mode->xfact;
- if (proj_xl_bound)
- proj_xl_bound -= pic->mode->xfact - 1;
-
- if (proj_xr_bound < 319)
- ++proj_xr_bound;
- proj_xr_bound *= pic->mode->xfact;
- proj_xr_bound += pic->mode->xfact - 1;
-#endif
- xl = x;
- while (xl > proj_xl_bound && (!IS_BOUNDARY(xl - 1, y, bounds[ytotal + xl -1])))
- --xl;
-
- while (x < proj_xr_bound && (!IS_BOUNDARY(x + 1, y, bounds[ytotal + x + 1])))
- ++x;
- xr = x;
-
- if (drawenable & GFX_MASK_VISUAL)
- memset(pic->visual_map->index_data + ytotal + xl, color, xr - xl + 1);
-
- if (drawenable & GFX_MASK_PRIORITY)
- memset(pic->priority_map->index_data + ytotal + xl, priority, xr - xl + 1);
-
- FILL_FUNCTION_RECURSIVE(pic, xl, xr, y, -1, bounds, legalcolor, legalmask, color, priority, drawenable,
- sci_titlebar_size);
- FILL_FUNCTION_RECURSIVE(pic, xl, xr, y, + 1, bounds, legalcolor, legalmask, color, priority, drawenable,
- sci_titlebar_size);
- }
-
- // Now finish the aux buffer
- bitmask = drawenable & (((color != 0xff) ? 1 : 0) | ((priority) ? 2 : 0) | ((control) ? 4 : 0));
-
-#ifdef DRAW_SCALED
-# ifdef FILL_RECURSIVE_DEBUG
- if (fillmagc)
-# endif
- _gfxr_auxbuf_propagate_changes(pic, bitmask);
-#endif
-}
-
-#undef SCALED_CHECK
-#undef IS_BOUNDARY
-
-#ifndef DRAW_SCALED
-# undef proj_xl_bound
-# undef proj_xr_bound
-#endif
-
-} // End of namespace Sci