From 527463dea2ee7ad30a030df0598ecf7a44853b57 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 8 May 2009 16:01:25 +0000 Subject: [PATCH] SCI: turn the various gfx filters from #define hacks into template funcs svn-id: r40386 --- engines/sci/gfx/gfx_pixmap_scale.cpp | 183 +++++++++++++++++++++++-- engines/sci/gfx/gfx_resource.cpp | 191 --------------------------- engines/sci/module.mk | 1 + 3 files changed, 172 insertions(+), 203 deletions(-) diff --git a/engines/sci/gfx/gfx_pixmap_scale.cpp b/engines/sci/gfx/gfx_pixmap_scale.cpp index 687f7b6e566..9173db5e7c3 100644 --- a/engines/sci/gfx/gfx_pixmap_scale.cpp +++ b/engines/sci/gfx/gfx_pixmap_scale.cpp @@ -29,14 +29,16 @@ ** EXTRA_BYTE_OFFSET: Extra source byte offset for copying (used on big-endian machines in 24 bit mode) */ -#include "sci/sci_memory.h" +#include "sci/gfx/gfx_system.h" +#include "sci/gfx/gfx_resource.h" +#include "sci/gfx/gfx_tools.h" namespace Sci { #define EXTEND_COLOR(x) (unsigned) ((((unsigned) x) << 24) | (((unsigned) x) << 16) | (((unsigned) x) << 8) | ((unsigned) x)) -#define PALETTE_MODE mode->palette -void FUNCNAME(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { +template +void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { SIZETYPE result_colors[GFX_PIC_COLORS]; SIZETYPE alpha_color = 0xffffffff & mode->alpha_mask; SIZETYPE alpha_ormask = 0; @@ -70,7 +72,7 @@ void FUNCNAME(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { int col; const PaletteEntry& color = pxm->palette->getColor(i); - if (PALETTE_MODE) + if (mode->palette) col = color.parent_index; else { col = mode->red_mask & ((EXTEND_COLOR(color.r)) >> mode->red_shift); @@ -188,7 +190,8 @@ void FUNCNAME(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { // End of macro definition -void FUNCNAME_LINEAR(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { +template +void _gfx_xlate_pixmap_linear(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { int xfact = mode->xfact; int yfact = mode->yfact; int line_step = (yfact < 2) ? 0 : 256 / (yfact & ~1); @@ -212,7 +215,7 @@ void FUNCNAME_LINEAR(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { } assert(bytespp == COPY_BYTES); - assert(!PALETTE_MODE); + assert(!mode->palette); masks[0] = mode->red_mask; masks[1] = mode->green_mask; @@ -337,7 +340,8 @@ static void gfx_apply_delta(unsigned int *color, int *delta, int factor) { #define REVERSE_ALPHA(foo) ((inverse_alpha) ? ~(foo) : (foo)) -void FUNCNAME_TRILINEAR(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { +template +void _gfx_xlate_pixmap_trilinear(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { int xfact = mode->xfact; int yfact = mode->yfact; int line_step = (yfact < 2) ? 0 : 256 / yfact; @@ -361,7 +365,7 @@ void FUNCNAME_TRILINEAR(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { } assert(bytespp == COPY_BYTES); - assert(!PALETTE_MODE); + assert(!mode->palette); masks[0] = mode->red_mask; masks[1] = mode->green_mask; @@ -376,7 +380,7 @@ void FUNCNAME_TRILINEAR(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { return; if (separate_alpha_map && !alpha_dest) - alpha_dest = pxm->alpha_map = (byte*)sci_malloc(pxm->index_width * xfact * pxm->index_height * yfact); + alpha_dest = pxm->alpha_map = (byte *)sci_malloc(pxm->index_width * xfact * pxm->index_height * yfact); src -= pxm->index_width + 1; @@ -484,10 +488,165 @@ void FUNCNAME_TRILINEAR(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { #undef X_CALC_INTENSITY_NORMAL #undef MAKE_PIXEL_TRILINEAR #undef MAKE_PIXEL -#undef FUNCNAME -#undef FUNCNAME_LINEAR -#undef FUNCNAME_TRILINEAR #undef SIZETYPE #undef EXTEND_COLOR + + +static void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { + switch (mode->bytespp) { + + case 1: + _gfx_xlate_pixmap_unfiltered<1, uint8, 0>(mode, pxm, scale); + break; + + case 2: + _gfx_xlate_pixmap_unfiltered<2, uint16, 0>(mode, pxm, scale); + break; + + case 3: +#ifdef SCUMM_BIG_ENDIAN + _gfx_xlate_pixmap_unfiltered<3, uint32, 1>(mode, pxm, scale); +#else + _gfx_xlate_pixmap_unfiltered<3, uint32, 0>(mode, pxm, scale); +#endif + break; + + case 4: + _gfx_xlate_pixmap_unfiltered<4, uint32, 0>(mode, pxm, scale); + break; + + default: + GFXERROR("Invalid mode->bytespp=%d\n", mode->bytespp); + + } + + if (pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX) { + pxm->width = pxm->index_width; + pxm->height = pxm->index_height; + } else { + pxm->width = pxm->index_width * mode->xfact; + pxm->height = pxm->index_height * mode->yfact; + } +} + +static void _gfx_xlate_pixmap_linear(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { + if (mode->palette || !scale) { // fall back to unfiltered + _gfx_xlate_pixmap_unfiltered(mode, pxm, scale); + return; + } + + pxm->width = pxm->index_width * mode->xfact; + pxm->height = pxm->index_height * mode->yfact; + + switch (mode->bytespp) { + + case 1: + _gfx_xlate_pixmap_linear<1, uint8, 0>(mode, pxm, scale); + break; + + case 2: + _gfx_xlate_pixmap_linear<2, uint16, 0>(mode, pxm, scale); + break; + + case 3: +#ifdef SCUMM_BIG_ENDIAN + _gfx_xlate_pixmap_linear<3, uint32, 1>(mode, pxm, scale); +#else + _gfx_xlate_pixmap_linear<3, uint32, 0>(mode, pxm, scale); +#endif + break; + + case 4: + _gfx_xlate_pixmap_linear<4, uint32, 0>(mode, pxm, scale); + break; + + default: + GFXERROR("Invalid mode->bytespp=%d\n", mode->bytespp); + + } + +} + +static void _gfx_xlate_pixmap_trilinear(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { + if (mode->palette || !scale) { // fall back to unfiltered + _gfx_xlate_pixmap_unfiltered(mode, pxm, scale); + return; + } + + pxm->width = pxm->index_width * mode->xfact; + pxm->height = pxm->index_height * mode->yfact; + + switch (mode->bytespp) { + case 1: + _gfx_xlate_pixmap_trilinear<1, uint8, 0>(mode, pxm, scale); + break; + + case 2: + _gfx_xlate_pixmap_trilinear<2, uint16, 0>(mode, pxm, scale); + break; + + case 3: +#ifdef SCUMM_BIG_ENDIAN + _gfx_xlate_pixmap_trilinear<3, uint32, 1>(mode, pxm, scale); +#else + _gfx_xlate_pixmap_trilinear<3, uint32, 0>(mode, pxm, scale); +#endif + break; + + case 4: + _gfx_xlate_pixmap_trilinear<4, uint32, 0>(mode, pxm, scale); + break; + + default: + GFXERROR("Invalid mode->bytespp=%d\n", mode->bytespp); + + } +} + +void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode, gfx_xlate_filter_t filter) { + int was_allocated = 0; + + if (mode->palette) { + if (pxm->palette && pxm->palette != mode->palette) + pxm->palette->mergeInto(mode->palette); + } + + + if (!pxm->data) { + pxm->data = (byte*)sci_malloc(mode->xfact * mode->yfact * pxm->index_width * pxm->index_height * mode->bytespp + 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 (!mode->alpha_mask && pxm->colors_nr() < GFX_PIC_COLORS) + pxm->alpha_map = (byte*)sci_malloc(mode->xfact * mode->yfact * pxm->index_width * pxm->index_height + 1); + } else + was_allocated = 1; + + switch (filter) { + case GFX_XLATE_FILTER_NONE: + _gfx_xlate_pixmap_unfiltered(mode, pxm, !(pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX)); + break; + + case GFX_XLATE_FILTER_LINEAR: + _gfx_xlate_pixmap_linear(mode, pxm, !(pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX)); + break; + + case GFX_XLATE_FILTER_TRILINEAR: + _gfx_xlate_pixmap_trilinear(mode, pxm, !(pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX)); + break; + + default: + GFXERROR("Attempt to filter pixmap %04x in invalid mode #%d\n", pxm->ID, filter); + + if (!was_allocated) { + if (!mode->alpha_mask && pxm->colors_nr() < GFX_PIC_COLORS) + free(pxm->alpha_map); + free(pxm->data); + } + } +} + + } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_resource.cpp b/engines/sci/gfx/gfx_resource.cpp index 387f6e596b7..0335a3ea216 100644 --- a/engines/sci/gfx/gfx_resource.cpp +++ b/engines/sci/gfx/gfx_resource.cpp @@ -202,197 +202,6 @@ gfx_pixmap_t *gfxr_endianness_adjust(gfx_pixmap_t *pixmap, gfx_mode_t *mode) { return pixmap; } -} // End of namespace Sci - -// Now construct the pixmap scaling functions -#define EXTRA_BYTE_OFFSET 0 -#define SIZETYPE uint8 -#define FUNCNAME _gfx_xlate_pixmap_unfiltered_1 -#define FUNCNAME_LINEAR _gfx_xlate_pixmap_linear_1 -#define FUNCNAME_TRILINEAR _gfx_xlate_pixmap_trilinear_1 -#define COPY_BYTES 1 -#include "gfx_pixmap_scale.cpp" -#undef COPY_BYTES - -#define SIZETYPE uint16 -#define FUNCNAME _gfx_xlate_pixmap_unfiltered_2 -#define FUNCNAME_LINEAR _gfx_xlate_pixmap_linear_2 -#define FUNCNAME_TRILINEAR _gfx_xlate_pixmap_trilinear_2 -#define COPY_BYTES 2 -#include "gfx_pixmap_scale.cpp" -#undef COPY_BYTES - -#ifdef SCUMM_BIG_ENDIAN -# undef EXTRA_BYTE_OFFSET -# define EXTRA_BYTE_OFFSET 1 -#endif // SCUMM_BIG_ENDIAN -#define SIZETYPE uint32 -#define FUNCNAME _gfx_xlate_pixmap_unfiltered_3 -#define FUNCNAME_LINEAR _gfx_xlate_pixmap_linear_3 -#define FUNCNAME_TRILINEAR _gfx_xlate_pixmap_trilinear_3 -#define COPY_BYTES 3 -#include "gfx_pixmap_scale.cpp" -#undef COPY_BYTES -#ifdef SCUMM_BIG_ENDIAN -# undef EXTRA_BYTE_OFFSET -# define EXTRA_BYTE_OFFSET 0 -#endif // SCUMM_BIG_ENDIAN - -#define SIZETYPE uint32 -#define FUNCNAME _gfx_xlate_pixmap_unfiltered_4 -#define FUNCNAME_LINEAR _gfx_xlate_pixmap_linear_4 -#define FUNCNAME_TRILINEAR _gfx_xlate_pixmap_trilinear_4 -#define COPY_BYTES 4 -#include "gfx_pixmap_scale.cpp" -#undef COPY_BYTES -#undef EXTRA_BYTE_OFFSET -#undef SIZETYPE - -namespace Sci { - -static void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { - switch (mode->bytespp) { - - case 1: - _gfx_xlate_pixmap_unfiltered_1(mode, pxm, scale); - break; - - case 2: - _gfx_xlate_pixmap_unfiltered_2(mode, pxm, scale); - break; - - case 3: - _gfx_xlate_pixmap_unfiltered_3(mode, pxm, scale); - break; - - case 4: - _gfx_xlate_pixmap_unfiltered_4(mode, pxm, scale); - break; - - default: - GFXERROR("Invalid mode->bytespp=%d\n", mode->bytespp); - - } - - if (pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX) { - pxm->width = pxm->index_width; - pxm->height = pxm->index_height; - } else { - pxm->width = pxm->index_width * mode->xfact; - pxm->height = pxm->index_height * mode->yfact; - } -} - -static void _gfx_xlate_pixmap_linear(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { - if (mode->palette || !scale) { // fall back to unfiltered - _gfx_xlate_pixmap_unfiltered(mode, pxm, scale); - return; - } - - pxm->width = pxm->index_width * mode->xfact; - pxm->height = pxm->index_height * mode->yfact; - - switch (mode->bytespp) { - - case 1: - _gfx_xlate_pixmap_linear_1(mode, pxm, scale); - break; - - case 2: - _gfx_xlate_pixmap_linear_2(mode, pxm, scale); - break; - - case 3: - _gfx_xlate_pixmap_linear_3(mode, pxm, scale); - break; - - case 4: - _gfx_xlate_pixmap_linear_4(mode, pxm, scale); - break; - - default: - GFXERROR("Invalid mode->bytespp=%d\n", mode->bytespp); - - } - -} - -static void _gfx_xlate_pixmap_trilinear(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { - if (mode->palette || !scale) { // fall back to unfiltered - _gfx_xlate_pixmap_unfiltered(mode, pxm, scale); - return; - } - - pxm->width = pxm->index_width * mode->xfact; - pxm->height = pxm->index_height * mode->yfact; - - switch (mode->bytespp) { - case 1: - _gfx_xlate_pixmap_trilinear_1(mode, pxm, scale); - break; - - case 2: - _gfx_xlate_pixmap_trilinear_2(mode, pxm, scale); - break; - - case 3: - _gfx_xlate_pixmap_trilinear_3(mode, pxm, scale); - break; - - case 4: - _gfx_xlate_pixmap_trilinear_4(mode, pxm, scale); - break; - - default: - GFXERROR("Invalid mode->bytespp=%d\n", mode->bytespp); - - } -} - -void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode, gfx_xlate_filter_t filter) { - int was_allocated = 0; - - if (mode->palette) { - if (pxm->palette && pxm->palette != mode->palette) - pxm->palette->mergeInto(mode->palette); - } - - - if (!pxm->data) { - pxm->data = (byte*)sci_malloc(mode->xfact * mode->yfact * pxm->index_width * pxm->index_height * mode->bytespp + 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 (!mode->alpha_mask && pxm->colors_nr() < GFX_PIC_COLORS) - pxm->alpha_map = (byte*)sci_malloc(mode->xfact * mode->yfact * pxm->index_width * pxm->index_height + 1); - } else - was_allocated = 1; - - switch (filter) { - case GFX_XLATE_FILTER_NONE: - _gfx_xlate_pixmap_unfiltered(mode, pxm, !(pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX)); - break; - - case GFX_XLATE_FILTER_LINEAR: - _gfx_xlate_pixmap_linear(mode, pxm, !(pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX)); - break; - - case GFX_XLATE_FILTER_TRILINEAR: - _gfx_xlate_pixmap_trilinear(mode, pxm, !(pxm->flags & GFX_PIXMAP_FLAG_SCALED_INDEX)); - break; - - default: - GFXERROR("Attempt to filter pixmap %04x in invalid mode #%d\n", pxm->ID, filter); - - if (!was_allocated) { - if (!mode->alpha_mask && pxm->colors_nr() < GFX_PIC_COLORS) - free(pxm->alpha_map); - free(pxm->data); - } - } -} - void gfxr_free_pic(gfxr_pic_t *pic) { gfx_free_pixmap(pic->visual_map); gfx_free_pixmap(pic->priority_map); diff --git a/engines/sci/module.mk b/engines/sci/module.mk index bcbbc46c7d4..cff633dbf33 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -37,6 +37,7 @@ MODULE_OBJS = \ gfx/font.o \ gfx/gfx_driver.o \ gfx/gfx_gui.o \ + gfx/gfx_pixmap_scale.o \ gfx/gfx_res_options.o \ gfx/gfx_resmgr.o \ gfx/gfx_resource.o \