scummvm/engines/sci/gfx/gfx_res_options.cpp
Willem Jan Palenstijn ced40b2266 Use new Palette class to manager pixmap palettes.
There are some remaining regressions with text colour in SCI1 games,
but overall it should fix more than it breaks.

svn-id: r39242
2009-03-08 20:17:01 +00:00

199 lines
5.0 KiB
C++

/* 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 inline int matches_patternlist(gfx_res_pattern_t *patterns, int nr, int val) {
int i;
for (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 inline 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 inline 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_assign(gfx_res_assign_t *conf, gfx_pixmap_t *pxm) {
if (pxm->palette)
pxm->palette->free();
pxm->palette = new Palette(conf->assign.palette.colors, conf->assign.palette.colors_nr);
pxm->palette->name = "res";
}
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)
apply_assign(&(conf->conf.assign), pxm);
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