/* 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_system.h" #include "sci/gfx/gfx_options.h" #include "sci/gfx/gfx_resmgr.h" namespace Sci { //#define DEBUG static int matches_patternlist(gfx_res_pattern_t *patterns, int nr, int val) { for (int i = 0; i < nr; i++) if (patterns[i].min <= val && patterns[i].max >= val) return 1; return 0; } #ifdef DEBUG static void print_pattern(gfx_res_pattern_t *pat) { fprintf(stderr, "[%d..%d]", pat->min, pat->max); } #endif static int resource_matches_patternlists(gfx_res_conf_t *conf, int type, int nr, int loop, int cel) { int loc; #ifdef DEBUG int i; fprintf(stderr, "[DEBUG:gfx-res] Trying to match against %d/%d/%d choices\n", conf->patterns_nr, conf->loops_nr, conf->cels_nr); for (i = 0; i < conf->patterns_nr; i++) { fprintf(stderr, "[DEBUG:gfx-res] Pat #%d: ", i); print_pattern(conf->patterns + i); fprintf(stderr, "\n"); } loc = conf->patterns_nr; for (i = 0; i < conf->loops_nr; i++) { fprintf(stderr, "[DEBUG:gfx-res] Loop #%d: ", i); print_pattern(conf->patterns + i + loc); fprintf(stderr, "\n"); } loc += conf->loops_nr; for (i = 0; i < conf->cels_nr; i++) { fprintf(stderr, "[DEBUG:gfx-res] Cel #%d: ", i); print_pattern(conf->patterns + i + loc); fprintf(stderr, "\n"); } #endif if (conf->patterns_nr && !matches_patternlist(conf->patterns, conf->patterns_nr, nr)) return 0; if (type == GFX_RESOURCE_TYPE_CURSOR) return 1; /* Otherwise, we must match at least the loop (pic) ** and, for views, the cel as well */ loc = conf->patterns_nr; if (conf->loops_nr && !matches_patternlist(conf->patterns + loc, conf->loops_nr, loop)) return 0; if (type != GFX_RESOURCE_TYPE_VIEW) return 1; loc += conf->loops_nr; if (!conf->cels_nr) return 1; return matches_patternlist(conf->patterns + loc, conf->cels_nr, cel); } static gfx_res_conf_t *find_match(gfx_res_conf_t *conflist, int type, int nr, int loop, int cel) { while (conflist) { if (resource_matches_patternlists(conflist, type, nr, loop, cel)) { #ifdef DEBUG fprintf(stderr, "[DEBUG:gfx-res] Found match!\n"); #endif return conflist; } conflist = conflist->next; } return NULL; } void apply_mod(gfx_res_mod_t *mod, gfx_pixmap_t *pxm) { Palette *pal = pxm->palette; int i, pal_size = pal ? pal->size() : 0; // Does not have a dynamically allocated palette? Must dup current one if (pal && pal->isShared()) { pal = pxm->palette->copy(); pxm->palette->free(); pxm->palette = pal; } switch (mod->type) { case GFX_RES_MULTIPLY_FIXED: { for (i = 0; i < pal_size; i++) { int v; #define UPDATE_COL(nm, idx) \ v = nm; \ v *= mod->mod.factor[idx]; \ v >>= 4; \ nm = (v > 255)? 255 : v; PaletteEntry c = pal->getColor(i); UPDATE_COL(c.r, 0); UPDATE_COL(c.g, 1); UPDATE_COL(c.b, 2); pal->setColor(i, c.r, c.g, c.b); #undef UPDATE_COL } break; } default: GFXERROR("Using unexpected visual resource modifier %d\n", mod->type); } } int gfx_get_res_config(gfx_options_t *options, gfx_pixmap_t *pxm) { int restype = GFXR_RES_TYPE(pxm->ID); int nr = GFXR_RES_NR(pxm->ID); int loop = pxm->loop; int cel = pxm->cel; gfx_res_conf_t *conf; #ifdef DEBUG fprintf(stderr, "[DEBUG:gfx-res] Trying to conf %d/%d/%d/%d (ID=%d)\n", restype, nr, loop, cel, pxm->ID); #endif if (pxm->ID < 0 || restype < 0 || restype >= GFX_RESOURCE_TYPES_NR) return 1; // Not appropriate conf = find_match(options->res_conf.assign[restype], restype, nr, loop, cel); if (conf) { // Assign palette if (pxm->palette) pxm->palette->free(); pxm->palette = new Palette(conf->conf.assign.assign.palette.colors, conf->conf.assign.assign.palette.colors_nr); pxm->palette->name = "res"; } conf = options->res_conf.mod[restype]; while (conf) { conf = find_match(conf, restype, nr, loop, cel); if (conf) { apply_mod(&(conf->conf.mod), pxm); conf = conf->next; } } fflush(NULL); return 0; } } // End of namespace Sci