mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 14:50:17 +00:00
4f436e311d
svn-id: r38393
220 lines
5.6 KiB
C++
220 lines
5.6 KiB
C++
/***************************************************************************
|
|
gfx_res_options.c Copyright (C) 2002 Christoph Reichenbach
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public Licence as
|
|
published by the Free Software Foundaton; either version 2 of the
|
|
Licence, or (at your option) any later version.
|
|
|
|
It is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
merchantibility or fitness for a particular purpose. See the
|
|
GNU General Public Licence for more details.
|
|
|
|
You should have received a copy of the GNU General Public Licence
|
|
along with this program; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
|
|
|
|
Please contact the maintainer for any program-related bug reports or
|
|
inquiries.
|
|
|
|
Current Maintainer:
|
|
|
|
Christoph Reichenbach (CR) <jameson@linuxgames.com>
|
|
|
|
***************************************************************************/
|
|
|
|
#include "sci/include/gfx_system.h"
|
|
#include "sci/include/gfx_options.h"
|
|
#include "sci/include/gfx_resmgr.h"
|
|
|
|
#include <ctype.h>
|
|
|
|
/*#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) {
|
|
/* Has a dynamically allocated palette? Must clean up */
|
|
if (!(pxm->flags & GFX_PIXMAP_FLAG_EXTERNAL_PALETTE)) {
|
|
if (pxm->colors)
|
|
free(pxm->colors);
|
|
pxm->flags |= GFX_PIXMAP_FLAG_EXTERNAL_PALETTE;
|
|
}
|
|
|
|
pxm->colors_nr = conf->assign.palette.colors_nr;
|
|
pxm->colors = conf->assign.palette.colors;
|
|
}
|
|
|
|
void
|
|
apply_mod(gfx_res_mod_t *mod, gfx_pixmap_t *pxm) {
|
|
gfx_pixmap_color_t *pal = pxm->colors;
|
|
int i, pal_size = pxm->colors_nr;
|
|
|
|
/* Does not have a dynamically allocated palette? Must dup current one */
|
|
if (pxm->flags & GFX_PIXMAP_FLAG_EXTERNAL_PALETTE) {
|
|
int size = sizeof(gfx_pixmap_color_t) * pal_size;
|
|
pxm->colors = (gfx_pixmap_color_t*)sci_malloc(size);
|
|
memcpy(pxm->colors, pal, size);
|
|
pal = pxm->colors;
|
|
pxm->flags &= ~GFX_PIXMAP_FLAG_EXTERNAL_PALETTE;
|
|
/* Flag for later deallocation */
|
|
}
|
|
|
|
switch (mod->type) {
|
|
|
|
case GFX_RES_MULTIPLY_FIXED: {
|
|
for (i = 0; i < pal_size; i++) {
|
|
int v;
|
|
|
|
#define UPDATE_COL(nm, idx) \
|
|
v = pal[i].nm; \
|
|
v *= mod->mod.factor[idx]; \
|
|
v >>= 4; \
|
|
pal[i].nm = (v > 255)? 255 : v;
|
|
|
|
UPDATE_COL(r, 0);
|
|
UPDATE_COL(g, 1);
|
|
UPDATE_COL(b, 2);
|
|
#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;
|
|
}
|