diff options
-rw-r--r-- | engines/sci/engine/game.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 20 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_options.h | 18 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_res_options.cpp | 4 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_res_options.h | 4 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.cpp | 74 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.h | 18 | ||||
-rw-r--r-- | engines/sci/gfx/operations.cpp | 19 | ||||
-rw-r--r-- | engines/sci/sci.cpp | 8 |
9 files changed, 158 insertions, 9 deletions
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index e1af9c7f64..c3bd69983d 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -217,12 +217,14 @@ 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); } diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 5372283895..ddf38e40a8 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -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)); diff --git a/engines/sci/gfx/gfx_options.h b/engines/sci/gfx/gfx_options.h index e6a2112286..76fbc23323 100644 --- a/engines/sci/gfx/gfx_options.h +++ b/engines/sci/gfx/gfx_options.h @@ -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 diff --git a/engines/sci/gfx/gfx_res_options.cpp b/engines/sci/gfx/gfx_res_options.cpp index a1b96c6dc0..187aafbbe8 100644 --- a/engines/sci/gfx/gfx_res_options.cpp +++ b/engines/sci/gfx/gfx_res_options.cpp @@ -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 diff --git a/engines/sci/gfx/gfx_res_options.h b/engines/sci/gfx/gfx_res_options.h index cc2979440e..bae9551663 100644 --- a/engines/sci/gfx/gfx_res_options.h +++ b/engines/sci/gfx/gfx_res_options.h @@ -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 diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp index 3533d7c067..a1b0fbe8ce 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -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; diff --git a/engines/sci/gfx/gfx_resmgr.h b/engines/sci/gfx/gfx_resmgr.h index 6bfdfa2e23..b699c87430 100644 --- a/engines/sci/gfx/gfx_resmgr.h +++ b/engines/sci/gfx/gfx_resmgr.h @@ -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: diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp index 9bcc951889..923e310d8c 100644 --- a/engines/sci/gfx/operations.cpp +++ b/engines/sci/gfx/operations.cpp @@ -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) { diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index c86d2bfbfb..1b9f5e4cf7 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -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"); |