mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-21 01:08:25 +00:00
SCI: turn the various gfx filters from #define hacks into template funcs
svn-id: r40386
This commit is contained in:
parent
e34c6316c6
commit
527463dea2
@ -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<int COPY_BYTES, typename SIZETYPE, int EXTRA_BYTE_OFFSET>
|
||||
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<int COPY_BYTES, typename SIZETYPE, int EXTRA_BYTE_OFFSET>
|
||||
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<int COPY_BYTES, typename SIZETYPE, int EXTRA_BYTE_OFFSET>
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user