- Wrapped all the code for custom graphics options around a CUSTOM_GRAPHICS_OPTIONS define. Most of these options don't work in 256-color mode, plus there is currently no way to actually set/change them somehow (other than modifying the code)

- Added a FIXME for the abuse of the pic_port_bounds graphics option - it's actually set by the game itself in kSetPort()
- Added some test code for setting palette intensity in KPalette() (currently disabled)

svn-id: r39794
This commit is contained in:
Filippos Karapetis 2009-04-01 20:32:45 +00:00
parent b6f6fdced4
commit 1e8bd16c1e
9 changed files with 158 additions and 9 deletions

View File

@ -217,11 +217,13 @@ int _reset_graphics_input(EngineState *s) {
}
int game_init_graphics(EngineState *s) {
#ifdef CUSTOM_GRAPHICS_OPTIONS
#ifndef WITH_PIC_SCALING
if (s->gfx_state->options->pic0_unscaled == 0)
warning("Pic scaling was disabled; your version of FreeSCI has no support for scaled pic drawing built in.");
s->gfx_state->options->pic0_unscaled = 1;
#endif
#endif
return _reset_graphics_input(s);
}

View File

@ -1269,10 +1269,25 @@ reg_t kPalette(EngineState *s, int funct_nr, int argc, reg_t *argv) {
case 3:
warning("STUB: kPalette() effect 3, clear flag to colors");
break;
case 4:
case 4: { // Set palette intensity
#if 0
// Colors 0 (black) and 255 (white) cannot be changed
int16 from = CLIP<int16>(1, 255, UKPV(2));
int16 to = CLIP<int16>(1, 255, UKPV(3));
int16 intensity = UKPV(4);
if (argc < 5 || UKPV(5) == 0) {
s->gfx_state->gfxResMan->setPaletteIntensity(from, to, intensity);
} else {
warning("kPalette: argv[5] != 0");
}
return s->r_acc;
#endif
warning("STUB: kPalette() effect 4, set color intensity");
break;
case 5: {
}
case 5: { // Find closest color
int r = UKPV(1);
int g = UKPV(2);
int b = UKPV(3);
@ -2360,6 +2375,7 @@ reg_t kSetPort(EngineState *s, int funct_nr, int argc, reg_t *argv) {
return s->r_acc;
}
// FIXME: this actually changes the picture port bounds, which are supposed to be user-defined...
s->gfx_state->options->pic_port_bounds = gfx_rect(UKPV(5), UKPV(4),
UKPV(3), UKPV(2));

View File

@ -29,7 +29,16 @@
#include "sci/gfx/gfx_resource.h"
#include "sci/gfx/gfx_tools.h"
// Define this to enable user-defined custom graphics options
// TODO: Most of these options don't work in 256-color mode, plus there
// is currently no way to actually set/change them somehow (other than
// modifying the code)
//#define CUSTOM_GRAPHICS_OPTIONS
#ifdef CUSTOM_GRAPHICS_OPTIONS
#include "sci/gfx/gfx_res_options.h"
#endif
namespace Sci {
@ -41,8 +50,8 @@ namespace Sci {
/* Clusters: Accumulate dirty rects, merging those that overlap (insert is O(n)) */
#define GFXOP_DIRTY_FRAMES_CLUSTERS 2
struct gfx_options_t {
#ifdef CUSTOM_GRAPHICS_OPTIONS
/* gfx_options_t: Contains all user options to the rendering pipeline */
/* See note in sci_conf.h for config_entry_t before changing types of
** variables */
@ -62,18 +71,21 @@ struct gfx_options_t {
gfx_xlate_filter_t view_xlate_filter;
gfx_xlate_filter_t pic_xlate_filter; /* Only relevant if (pic0_unscaled) */
gfx_xlate_filter_t text_xlate_filter;
gfx_res_fullconf_t res_conf; /* Resource customisation: Per-resource palettes etc. */
int dirty_frames;
int workarounds; /* Workaround flags- see below */
int workarounds; // Workaround flags - see below
#endif
// FIXME: This option is abused: pic_port_bounds is actually set by the game itself in kSetPort()
rect_t pic_port_bounds;
};
#ifdef CUSTOM_GRAPHICS_OPTIONS
/* SQ3 counts whitespaces towards the total text size, as does gfxop_get_text_params() if this is set: */
#define GFX_WORKAROUND_WHITESPACE_COUNT (1 << 0)
#endif
} // End of namespace Sci

View File

@ -27,6 +27,8 @@
#include "sci/gfx/gfx_options.h"
#include "sci/gfx/gfx_resmgr.h"
#ifdef CUSTOM_GRAPHICS_OPTIONS
namespace Sci {
//#define DEBUG
@ -184,3 +186,5 @@ int gfx_get_res_config(gfx_options_t *options, gfx_pixmap_t *pxm) {
}
} // End of namespace Sci
#endif

View File

@ -28,6 +28,8 @@
#ifndef SCI_GFX_GFX_RES_OPTIONS_H
#define SCI_GFX_GFX_RES_OPTIONS_H
#ifdef CUSTOM_GRAPHICS_OPTIONS
#include "sci/gfx/gfx_resource.h"
#include "sci/gfx/gfx_resmgr.h"
@ -93,4 +95,6 @@ int gfx_get_res_config(gfx_options_t *options, gfx_pixmap_t *pxm);
} // End of namespace Sci
#endif
#endif // SCI_GFX_GFX_RES_OPTIONS_H

View File

@ -88,8 +88,13 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic
basic_style.brush_mode = GFX_BRUSH_MODE_SCALED;
basic_style.pic_port_bounds = _options->pic_port_bounds;
#ifdef CUSTOM_GRAPHICS_OPTIONS
style.line_mode = _options->pic0_line_mode;
style.brush_mode = _options->pic0_brush_mode;
#else
style.line_mode = GFX_LINE_MODE_CORRECT;
style.brush_mode = GFX_BRUSH_MODE_RANDOM_ELLIPSES;
#endif
style.pic_port_bounds = _options->pic_port_bounds;
if (!res || !res->data)
@ -119,7 +124,11 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic
memcpy(scaled_pic->undithered_buffer, scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer_size);
#ifdef CUSTOM_GRAPHICS_OPTIONS
gfxr_dither_pic0(scaled_pic, _options->pic0_dither_mode, _options->pic0_dither_pattern);
#else
gfxr_dither_pic0(scaled_pic, GFXR_DITHER_MODE_D256, GFXR_DITHER_PATTERN_SCALED);
#endif
}
// Mark default palettes
@ -142,9 +151,13 @@ int GfxResManager::getOptionsHash(gfx_resource_type_t type) {
if (_version >= SCI_VERSION_01_VGA)
return _options->pic_port_bounds.y;
else
#ifdef CUSTOM_GRAPHICS_OPTIONS
return (_options->pic0_unscaled) ? 0x10000 : (_options->pic0_dither_mode << 12)
| (_options->pic0_dither_pattern << 8) | (_options->pic0_brush_mode << 4)
| (_options->pic0_line_mode);
#else
return 0x10000 | (GFXR_DITHER_PATTERN_SCALED << 8) | (GFX_BRUSH_MODE_RANDOM_ELLIPSES << 4) | GFX_LINE_MODE_CORRECT;
#endif
case GFX_RESOURCE_TYPE_FONT:
case GFX_RESOURCE_TYPE_CURSOR:
@ -258,7 +271,8 @@ void GfxResManager::setStaticPalette(Palette *newPalette)
_staticPalette->mergeInto(_driver->mode->palette);
}
#if 0
// FIXME: the options for GFX_MASK_VISUAL are actually unused
#define XLATE_AS_APPROPRIATE(key, entry) \
if (maps & key) { \
if (res->unscaled_data.pic&& (force || !res->unscaled_data.pic->entry->data)) { \
@ -271,9 +285,20 @@ void GfxResManager::setStaticPalette(Palette *newPalette)
gfx_xlate_pixmap(res->scaled_data.pic->entry, mode, filter); \
} \
}
#endif
#define XLATE_AS_APPROPRIATE(key, entry) \
if (maps & key) { \
if (res->unscaled_data.pic&& (force || !res->unscaled_data.pic->entry->data)) { \
gfx_xlate_pixmap(res->unscaled_data.pic->entry, mode, filter); \
} if (scaled && res->scaled_data.pic && (force || !res->scaled_data.pic->entry->data)) { \
gfx_xlate_pixmap(res->scaled_data.pic->entry, mode, filter); \
} \
}
static gfxr_pic_t *gfxr_pic_xlate_common(gfx_resource_t *res, int maps, int scaled, int force, gfx_mode_t *mode,
gfx_xlate_filter_t filter, int endianize, gfx_options_t *options) {
XLATE_AS_APPROPRIATE(GFX_MASK_VISUAL, visual_map);
XLATE_AS_APPROPRIATE(GFX_MASK_PRIORITY, priority_map);
XLATE_AS_APPROPRIATE(GFX_MASK_CONTROL, control_map);
@ -285,6 +310,7 @@ static gfxr_pic_t *gfxr_pic_xlate_common(gfx_resource_t *res, int maps, int scal
}
#undef XLATE_AS_APPROPRIATE
gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_palette, bool scaled) {
gfxr_pic_t *npic = NULL;
IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_PIC];
@ -301,11 +327,17 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale
gfxr_pic_t *pic;
gfxr_pic_t *unscaled_pic = NULL;
#ifdef CUSTOM_GRAPHICS_OPTIONS
if (_options->pic0_unscaled) {
need_unscaled = 0;
pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _version >= SCI_VERSION_01_VGA);
} else
pic = gfxr_init_pic(_driver->mode, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _version >= SCI_VERSION_01_VGA);
#else
need_unscaled = 0;
pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _version >= SCI_VERSION_01_VGA);
#endif
if (!pic) {
GFXERROR("Failed to allocate scaled pic!\n");
return NULL;
@ -330,7 +362,11 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale
if (!res) {
res = (gfx_resource_t *)sci_malloc(sizeof(gfx_resource_t));
res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num);
#ifdef CUSTOM_GRAPHICS_OPTIONS
res->lock_sequence_nr = _options->buffer_pics_nr;
#else
res->lock_sequence_nr = 0;
#endif
resMap[num] = res;
} else {
gfxr_free_pic(res->scaled_data.pic);
@ -342,14 +378,23 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale
res->scaled_data.pic = pic;
res->unscaled_data.pic = unscaled_pic;
} else {
#ifdef CUSTOM_GRAPHICS_OPTIONS
res->lock_sequence_nr = _options->buffer_pics_nr; // Update lock counter
#else
res->lock_sequence_nr = 0;
#endif
}
must_post_process_pic = res->scaled_data.pic->visual_map->data == NULL;
// If the pic was only just drawn, we'll have to endianness-adjust it now
#ifdef CUSTOM_GRAPHICS_OPTIONS
npic = gfxr_pic_xlate_common(res, maps, scaled || _options->pic0_unscaled, 0, _driver->mode,
_options->pic_xlate_filter, 0, _options);
#else
npic = gfxr_pic_xlate_common(res, maps, 1, 0, _driver->mode,
GFX_XLATE_FILTER_NONE, 0, _options);
#endif
if (must_post_process_pic) {
@ -411,7 +456,11 @@ gfxr_pic_t *GfxResManager::addToPic(int old_nr, int new_nr, int flags, int old_d
gfxr_pic_t *pic = NULL;
gfx_resource_t *res = NULL;
int hash = getOptionsHash(GFX_RESOURCE_TYPE_PIC);
#ifdef CUSTOM_GRAPHICS_OPTIONS
int need_unscaled = !(_options->pic0_unscaled) && (_driver->mode->xfact != 1 || _driver->mode->yfact != 1);
#else
int need_unscaled = 1;
#endif
res = resMap.contains(old_nr) ? resMap[old_nr] : NULL;
@ -426,22 +475,35 @@ gfxr_pic_t *GfxResManager::addToPic(int old_nr, int new_nr, int flags, int old_d
}
}
#ifdef CUSTOM_GRAPHICS_OPTIONS
if (_options->pic0_unscaled) // Unscale priority map, if we scaled it earlier
#endif
_gfxr_unscale_pixmap_index_data(res->scaled_data.pic->priority_map, _driver->mode);
// The following two operations are needed when returning scaled maps (which is always the case here)
#ifdef CUSTOM_GRAPHICS_OPTIONS
res->lock_sequence_nr = _options->buffer_pics_nr;
#else
res->lock_sequence_nr = 0;
#endif
calculatePic(res->scaled_data.pic, need_unscaled ? res->unscaled_data.pic : NULL,
flags | DRAWPIC01_FLAG_OVERLAID_PIC, default_palette, new_nr);
res->mode = MODE_INVALID; // Invalidate
#ifdef CUSTOM_GRAPHICS_OPTIONS
if (_options->pic0_unscaled) // Scale priority map again, if needed
#endif
res->scaled_data.pic->priority_map = gfx_pixmap_scale_index_data(res->scaled_data.pic->priority_map, _driver->mode);
{
int old_ID = get_pic_id(res);
set_pic_id(res, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, new_nr)); // To ensure that our graphical translation optoins work properly
set_pic_id(res, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, new_nr)); // To ensure that our graphical translation options work properly
#ifdef CUSTOM_GRAPHICS_OPTIONS
pic = gfxr_pic_xlate_common(res, GFX_MASK_VISUAL, 1, 1, _driver->mode, _options->pic_xlate_filter, 1, _options);
#else
pic = gfxr_pic_xlate_common(res, GFX_MASK_VISUAL, 1, 1, _driver->mode, GFX_XLATE_FILTER_NONE, 1, _options);
#endif
set_pic_id(res, old_ID);
}
@ -539,8 +601,12 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) {
}
if (!cel_data->data) {
#ifdef CUSTOM_GRAPHICS_OPTIONS
gfx_get_res_config(_options, cel_data);
gfx_xlate_pixmap(cel_data, _driver->mode, _options->view_xlate_filter);
#else
gfx_xlate_pixmap(cel_data, _driver->mode, GFX_XLATE_FILTER_NONE);
#endif
gfxr_endianness_adjust(cel_data, _driver->mode);
}
@ -617,8 +683,12 @@ gfx_pixmap_t *GfxResManager::getCursor(int num) {
} else {
gfx_free_pixmap(res->unscaled_data.pointer);
}
#ifdef CUSTOM_GRAPHICS_OPTIONS
gfx_get_res_config(_options, cursor);
gfx_xlate_pixmap(cursor, _driver->mode, _options->cursor_xlate_filter);
#else
gfx_xlate_pixmap(cursor, _driver->mode, GFX_XLATE_FILTER_NONE);
#endif
gfxr_endianness_adjust(cursor, _driver->mode);
res->unscaled_data.pointer = cursor;

View File

@ -226,6 +226,24 @@ public:
// Set static palette and merge it into the global palette
void setStaticPalette(Palette *newPalette);
#if 0
void setPaletteIntensity(int16 from, int16 to, int16 intensity) {
Palette *pal = _staticPalette->getref();
for (uint16 i = 0; i < _driver->mode->palette->size(); i++) {
byte r = pal->getColor(i).r * intensity / 100;
byte g = pal->getColor(i).g * intensity / 100;
byte b = pal->getColor(i).b * intensity / 100;
pal->makeSystemColor(i, PaletteEntry(r, g, b));
}
pal->mergeInto(_driver->mode->palette);
_driver->install_palette(_driver, pal);
pal->unmerge();
pal->free();
}
#endif
int getColorCount() { return _staticPalette ? _staticPalette->size() : 0; }
private:

View File

@ -367,7 +367,11 @@ static void _gfxop_add_dirty(gfx_state_t *state, rect_t box) {
if (state->disable_dirty)
return;
#ifdef CUSTOM_GRAPHICS_OPTIONS
state->dirty_rects = gfxdr_add_dirty(state->dirty_rects, box, state->options->dirty_frames);
#else
state->dirty_rects = gfxdr_add_dirty(state->dirty_rects, box, GFXOP_DIRTY_FRAMES_CLUSTERS);
#endif
}
static void _gfxop_add_dirty_x(gfx_state_t *state, rect_t box) {
@ -1803,7 +1807,9 @@ static int _gfxop_set_pic(gfx_state_t *state) {
_gfxop_install_pixmap(state->driver, state->pic->visual_map);
#ifdef CUSTOM_GRAPHICS_OPTIONS
if (state->options->pic0_unscaled)
#endif
state->pic->priority_map = gfx_pixmap_scale_index_data(state->pic->priority_map, state->driver->mode);
return state->driver->set_static_buffer(state->driver, state->pic->visual_map, state->pic->priority_map);
}
@ -1896,8 +1902,12 @@ int gfxop_get_text_params(gfx_state_t *state, int font_nr, const char *text, int
return GFX_ERROR;
}
#ifdef CUSTOM_GRAPHICS_OPTIONS
textsplits = gfxr_font_calculate_size(font, maxwidth, text, width, height, lines_nr, lineheight, lastline_width,
(state->options->workarounds & GFX_WORKAROUND_WHITESPACE_COUNT) | text_flags);
#else
textsplits = gfxr_font_calculate_size(font, maxwidth, text, width, height, lines_nr, lineheight, lastline_width, text_flags);
#endif
if (!textsplits) {
GFXERROR("Could not calculate text size!");
@ -1941,9 +1951,14 @@ gfx_text_handle_t *gfxop_new_text(gfx_state_t *state, int font_nr, char *text, i
handle->valign = valign;
handle->line_height = font->line_height;
#ifdef CUSTOM_GRAPHICS_OPTIONS
handle->lines = gfxr_font_calculate_size(font, maxwidth, handle->text, &(handle->width), &(handle->height), &(handle->lines_nr),
NULL, NULL, ((state->options->workarounds & GFX_WORKAROUND_WHITESPACE_COUNT) ?
kFontCountWhitespace : 0) | flags);
#else
handle->lines = gfxr_font_calculate_size(font, maxwidth, handle->text, &(handle->width), &(handle->height), &(handle->lines_nr),
NULL, NULL, flags);
#endif
if (!handle->lines) {
free(handle->text);
@ -2054,7 +2069,11 @@ int gfxop_draw_text(gfx_state_t *state, gfx_text_handle_t *handle, rect_t zone)
gfx_pixmap_t *pxm = handle->text_pixmaps[i];
if (!pxm->data) {
#ifdef CUSTOM_GRAPHICS_OPTIONS
gfx_xlate_pixmap(pxm, state->driver->mode, state->options->text_xlate_filter);
#else
gfx_xlate_pixmap(pxm, state->driver->mode, GFX_XLATE_FILTER_NONE);
#endif
gfxr_endianness_adjust(pxm, state->driver->mode); // FIXME: resmgr layer!
}
if (!pxm) {

View File

@ -248,7 +248,9 @@ Common::Error SciEngine::run() {
// Default config:
gfx_options_t gfx_options;
gfx_options.workarounds = 0;
gfx_options.pic_port_bounds = gfx_rect(0, 10, 320, 190);
#ifdef CUSTOM_GRAPHICS_OPTIONS
gfx_options.buffer_pics_nr = 0;
gfx_options.pic0_unscaled = 1;
gfx_options.pic0_dither_mode = GFXR_DITHER_MODE_D256;
@ -260,12 +262,14 @@ Common::Error SciEngine::run() {
gfx_options.pic_xlate_filter = GFX_XLATE_FILTER_NONE;
gfx_options.text_xlate_filter = GFX_XLATE_FILTER_NONE;
gfx_options.dirty_frames = GFXOP_DIRTY_FRAMES_CLUSTERS;
gfx_options.pic_port_bounds = gfx_rect(0, 10, 320, 190);
for (int i = 0; i < GFX_RESOURCE_TYPES_NR; i++) {
gfx_options.res_conf.assign[i] = NULL;
gfx_options.res_conf.mod[i] = NULL;
}
gfx_options.workarounds = 0;
// Default config ends
#endif
if (gfxop_init(_resmgr->_sciVersion, &gfx_state, &gfx_options, _resmgr)) {
fprintf(stderr, "Graphics initialization failed. Aborting...\n");