Further objectification of the graphics resource manager

svn-id: r39499
This commit is contained in:
Filippos Karapetis 2009-03-17 23:30:57 +00:00
parent 4edee56b3f
commit e546c60948
7 changed files with 349 additions and 355 deletions

View File

@ -874,7 +874,13 @@ reg_t kIsItSkip(EngineState *s, int funct_nr, int argc, reg_t *argv) {
gfxr_view_t *res = NULL;
gfx_pixmap_t *pxm = NULL;
if (!(res = gfxr_get_view(s->gfx_state->resstate, view, &loop, &cel, 0))) {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(s->gfx_state->resstate);
res = _gfx->getView(view, &loop, &cel, 0);
delete _gfx;
if (!res) {
GFXWARN("Attempt to get cel parameters for invalid view %d\n", view);
return make_reg(0, -1);
}
@ -2348,9 +2354,14 @@ reg_t kSetPort(EngineState *s, int funct_nr, int argc, reg_t *argv) {
s->gfx_state->options->pic_port_bounds = gfx_rect(UKPV(5), UKPV(4),
UKPV(3), UKPV(2));
// FIXME: Should really only invalidate all loaded pic resources here;
// this is overkill
gfxr_free_all_resources(s->gfx_state->resstate);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(s->gfx_state->resstate);
_gfx->freeAllResources();
delete _gfx;
break;
}

View File

@ -864,6 +864,10 @@ int c_viewinfo(EngineState *s) {
else {
sciprintf("has %d loops:\n", loops);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(s->gfx_state->resstate);
for (i = 0; i < loops; i++) {
int j, cels;
@ -874,10 +878,11 @@ int c_viewinfo(EngineState *s) {
Common::Point mod;
if (con_can_handle_pixmaps()) {
view_pixmaps = gfxr_get_view(s->gfx_state->resstate, view, &i, &j, palette);
view_pixmaps = _gfx->getView(view, &i, &j, palette);
con_insert_pixmap(gfx_clone_pixmap(view_pixmaps->loops[i].cels[j], s->gfx_state->driver->mode));
}
delete _gfx;
gfxop_get_cel_parameters(s->gfx_state, view, i, j, &width, &height, &mod);
sciprintf(" cel %d: size %dx%d, adj+(%d,%d)\n", j, width, height, mod.x, mod.y);
@ -2011,7 +2016,11 @@ static int c_gfx_flush_resources(EngineState *s) {
gfxop_set_pointer_cursor(s->gfx_state, GFXOP_NO_POINTER);
sciprintf("Flushing resources...\n");
s->visual->widfree(GFXW(s->visual));
gfxr_free_all_resources(s->gfx_state->resstate);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(s->gfx_state->resstate);
_gfx->freeAllResources();
delete _gfx;
s->visual = NULL;
return 0;

View File

@ -100,49 +100,26 @@ struct gfx_resstate_t {
};
gfx_resstate_t *gfxr_new_resource_manager(int version, gfx_options_t *options,
gfx_driver_t *driver, ResourceManager *resManager);
/* Allocates and initializes a new resource manager
** Parameters: (int) version: Interpreter version
** (gfx_options_t *): Pointer to all relevant drawing options
** (gfx_driver_t *): The graphics driver (needed for capability flags and the mode
** structure)
** (void *) misc_payload: Additional information for the interpreter's
** resource loaders
** Returns : (gfx_resstate_t *): A newly allocated resource manager
** The options are considered to be read-only, as they belong to the overlying state object.
*/
void gfxr_free_resource_manager(gfx_resstate_t *state);
/* Frees a previously allocated resource manager, and all allocated resources.
** Parameters: (gfx_resstate_t *) state: The state manager to free
** Return : (void)
*/
void gfxr_free_all_resources(gfx_resstate_t *state);
/* Frees all resources currently allocated
** Parameter: (gfx_resstate_t *) state: The state to do this on
** Returns : (void)
** This function is intended to be used primarily for debugging.
*/
void gfxr_free_tagged_resources(gfx_resstate_t *state);
/* Frees all tagged resources.
** Parameters: (gfx_resstate_t *) state: The state to alter
** Returns : (void)
** Resources are tagged by calling gfx_tag_resources(), and untagged by calling the
** approprate dereferenciation function.
** Note that this function currently only affects view resources, as pic resources are
** treated differently, while font and cursor resources are relatively rare.
*/
class GfxResManager {
public:
GfxResManager(gfx_resstate_t *state) : _state(state) {}
~GfxResManager() {}
/* Calculates a unique hash value for the specified options/type setup
** Parameters: (gfx_resource_type_t) type: The type the hash is to be generated for
** Returns : (int) A hash over the values of the options entries, covering entries iff
** they are relevant for the specified type
** Covering more entries than relevant may slow down the system when options are changed,
** while covering less may result in invalid cached data being used.
** Only positive values may be returned, as negative values are used internally by the generic
** resource manager code.
** Also, only the lower 20 bits are available to the interpreter.
** (Yes, this isn't really a "hash" in the traditional sense...)
*/
int getOptionsHash(gfx_resource_type_t type);
/* 'Tags' all resources for deletion
** Paramters: (void)
** Returns : (void)
@ -150,6 +127,7 @@ public:
*/
void tagResources() { (_state->tag_lock_counter)++; }
/* Retreives an SCI0/SCI01 mouse cursor
** Parameters: (int) num: The cursor number
** Returns : (gfx_font_t *) The approprate cursor as a pixmap, or NULL on error
@ -174,6 +152,20 @@ public:
gfx_bitmap_font_t *getFont(int num, bool scaled = false);
/* Retreives a translated view cel
** Parameters:
** (int) nr: The view number
** (int *) loop: Pointer to a variable containing the loop number
** (int *) cel: Pointer to a variable containing the cel number
** (int) palette: The palette to use
** Returns : (gfx_view_t *) The relevant view, or NULL if nr was invalid
** loop and cel are given as pointers in order to allow the underlying variables to be
** modified if they are invalid (this is relevant for SCI version 0, where invalid
** loop and cel numbers have to be interpreted as 'maximum' or 'minimum' by the interpreter)
*/
gfxr_view_t *getView(int nr, int *loop, int *cel, int palette);
/* Retreives a displayable (translated) pic resource
** Parameters: (int) nr: Number of the pic resource
** (int) maps: The maps to translate (ORred GFX_MASK_*)
@ -187,90 +179,71 @@ public:
gfxr_pic_t *getPic(int num, int maps, int flags, int default_palette, bool scaled = false);
/* Retrieves a displayable (translated) pic resource written ontop of an existing pic
** Parameters: (int) old_nr: Number of the pic resource to write on
** (int) new_nr: Number of the pic resource that is to be added
** (int) flags: Interpreter-dependant pic flags
** (int) default_palette: The default palette to use for drawing (if applicable)
** (int) scaled: Whether to return the scaled maps, or the unscaled
** ones (which may be identical) for some special operations.
** Returns : (gfx_pic_t *) The appropriate pic resource with all maps as index (but not
** neccessarily translated) data.
** This function invalidates the cached pic pointed to by old_nr in the cache. While subsequent
** addToPic() writes will still modify the 'invalidated' pic, gfxr_get_pic() operations will
** cause it to be removed from the cache and to be replaced by a clean version.
*/
gfxr_pic_t *addToPic(int old_nr, int new_nr, int flags, int old_default_palette, int default_palette);
/* Determines whether support for pointers with more than two colors is required
** Returns : (bool) false if no support for multi-colored pointers is required, true
** otherwise
*/
bool multicoloredPointers() { return _state->version > SCI_VERSION_1; }
/* Frees all resources currently allocated
** Parameter: (void)
** Returns : (void)
** This function is intended to be used primarily for debugging.
*/
void freeAllResources();
/* Frees all tagged resources.
** Parameters: (void)
** Returns : (void)
** Resources are tagged by calling gfx_tag_resources(), and untagged by calling the
** approprate dereferenciation function.
** Note that this function currently only affects view resources, as pic resources are
** treated differently, while font and cursor resources are relatively rare.
*/
void freeTaggedResources();
/* Frees a previously allocated resource manager, and all allocated resources.
** Parameters: (void)
** Return : (void)
*/
void freeResManager();
private:
gfx_resstate_t *_state;
};
gfxr_pic_t *gfxr_add_to_pic(gfx_resstate_t *state, int old_nr, int new_nr, int maps, int flags,
int old_default_palette, int default_palette, int scaled);
/* Retreives a displayable (translated) pic resource written ontop of an existing pic
** Parameters: (gfx_resstate_t *) state: The resource state
** (int) old_nr: Number of the pic resource to write on
** (int) new_nr: Number of the pic resource that is to be added
** (int) maps: The maps to translate (ORred GFX_MASK_*)
** (int) flags: Interpreter-dependant pic flags
** (int) default_palette: The default palette to use for drawing (if applicable)
** (int) scaled: Whether to return the scaled maps, or the unscaled
** ones (which may be identical) for some special operations.
** Returns : (gfx_pic_t *) The appropriate pic resource with all maps as index (but not
** neccessarily translated) data.
** This function invalidates the cached pic pointed to by old_nr in the cache. While subsequent
** gfxr_add_to_pic() writes will still modify the 'invalidated' pic, gfxr_get_pic() operations will
** cause it to be removed from the cache and to be replaced by a clean version.
*/
gfxr_view_t *gfxr_get_view(gfx_resstate_t *state, int nr, int *loop, int *cel, int palette);
/* Retreives a translated view cel
** Parameters: (gfx_resstate_t *) state: The resource state
** (int) nr: The view number
** (int *) loop: Pointer to a variable containing the loop number
** (int *) cel: Pointer to a variable containing the cel number
** (int) palette: The palette to use
** Returns : (gfx_view_t *) The relevant view, or NULL if nr was invalid
** loop and cel are given as pointers in order to allow the underlying variables to be
** modified if they are invalid (this is relevant for SCI version 0, where invalid
** loop and cel numbers have to be interpreted as 'maximum' or 'minimum' by the interpreter)
*/
/* =========================== */
/* Interpreter-dependant stuff */
/* =========================== */
int gfxr_interpreter_options_hash(gfx_resource_type_t type, int version,
gfx_options_t *options, int palette);
/* Calculates a unique hash value for the specified options/type setup
** Parameters: (gfx_resource_type_t) type: The type the hash is to be generated for
** (int) version: The interpreter type and version
** (gfx_options_t *) options: The options to hashify
** (int) palette: The palette to use (FIXME: should this be here?)
** Returns : (int) A hash over the values of the options entries, covering entries iff
** they are relevant for the specified type
** Covering more entries than relevant may slow down the system when options are changed,
** while covering less may result in invalid cached data being used.
** Only positive values may be returned, as negative values are used internally by the generic
** resource manager code.
** Also, only the lower 20 bits are available to the interpreter.
** (Yes, this isn't really a "hash" in the traditional sense...)
*/
int gfxr_interpreter_calculate_pic(gfx_resstate_t *state, gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic,
int flags, int default_palette, int nr);
/* Instructs the interpreter-specific code to calculate a picture
** Parameters: (gfx_resstate_t *) state: The resource state, containing options and version information
** (gfxr_pic_t *) scaled_pic: The pic structure that is to be written to
** (gfxr_pic_t *) unscaled_pic: The pic structure the unscaled pic is to be written to,
** or NULL if it isn't needed.
** (int) flags: Pic drawing flags (interpreter dependant)
** (int) default_palette: The default palette to use for pic drawing (interpreter dependant)
** (int) nr: pic resource number
** Returns : (int) GFX_ERROR if the resource could not be found, GFX_OK otherwise
*/
gfxr_view_t *gfxr_interpreter_get_view(ResourceManager& resourceManager, int nr, int palette, Palette* staticPalette, int version);
/* Instructs the interpreter-specific code to calculate a view
** Parameters: (ResourceManager& ) resourceManager: The resource manager
** (int) nr: The view resource number
** (int) palette: The palette number to use
** (Palette*) staticPalette: The static palette to use in VGA games
** (int) version: The interpreter version
** Returns : (gfx_view_t *) The appropriate view, or NULL on error
// FIXME: get rid of this
gfx_resstate_t *gfxr_new_resource_manager(int version, gfx_options_t *options,
gfx_driver_t *driver, ResourceManager *resManager);
/* Allocates and initializes a new resource manager
** Parameters: (int) version: Interpreter version
** (gfx_options_t *): Pointer to all relevant drawing options
** (gfx_driver_t *): The graphics driver (needed for capability flags and the mode
** structure)
** (void *) misc_payload: Additional information for the interpreter's
** resource loaders
** Returns : (gfx_resstate_t *): A newly allocated resource manager
** The options are considered to be read-only, as they belong to the overlying state object.
*/
} // End of namespace Sci

View File

@ -272,7 +272,12 @@ static void _gfxop_full_pointer_refresh(gfx_state_t *state) {
static int _gfxop_buffer_propagate_box(gfx_state_t *state, rect_t box, gfx_buffer_t buffer);
gfx_pixmap_t *_gfxr_get_cel(gfx_state_t *state, int nr, int *loop, int *cel, int palette) {
gfxr_view_t *view = gfxr_get_view(state->resstate, nr, loop, cel, palette);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
gfxr_view_t *view = _gfx->getView(nr, loop, cel, palette);
delete _gfx;
gfxr_loop_t *indexed_loop;
if (!view)
@ -504,7 +509,12 @@ int gfxop_set_parameter(gfx_state_t *state, char *attribute, char *value) {
int gfxop_exit(gfx_state_t *state) {
BASIC_CHECKS(GFX_ERROR);
gfxr_free_resource_manager(state->resstate);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
_gfx->freeResManager();
delete _gfx;
if (state->control_map) {
gfx_free_pixmap(state->control_map);
@ -1171,7 +1181,13 @@ int gfxop_update(gfx_state_t *state) {
if (state->tag_mode) {
// This usually happens after a pic and all resources have been drawn
gfxr_free_tagged_resources(state->resstate);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
_gfx->freeTaggedResources();
delete _gfx;
state->tag_mode = 0;
}
@ -1713,7 +1729,11 @@ int gfxop_lookup_view_get_loops(gfx_state_t *state, int nr) {
BASIC_CHECKS(GFX_ERROR);
view = gfxr_get_view(state->resstate, nr, &loop, &cel, 0);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
view = _gfx->getView(nr, &loop, &cel, 0);
delete _gfx;
if (!view) {
GFXWARN("Attempt to retrieve number of loops from invalid view %d\n", nr);
@ -1729,7 +1749,11 @@ int gfxop_lookup_view_get_cels(gfx_state_t *state, int nr, int loop) {
BASIC_CHECKS(GFX_ERROR);
view = gfxr_get_view(state->resstate, nr, &real_loop, &cel, 0);
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
view = _gfx->getView(nr, &real_loop, &cel, 0);
delete _gfx;
if (!view) {
GFXWARN("Attempt to retrieve number of cels from invalid/broken view %d\n", nr);
@ -1744,7 +1768,13 @@ int gfxop_lookup_view_get_cels(gfx_state_t *state, int nr, int loop) {
int gfxop_check_cel(gfx_state_t *state, int nr, int *loop, int *cel) {
BASIC_CHECKS(GFX_ERROR);
if (!gfxr_get_view(state->resstate, nr, loop, cel, 0)) {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
gfxr_view_t *testView = _gfx->getView(nr, loop, cel, 0);
delete _gfx;
if (!testView) {
GFXWARN("Attempt to verify loop/cel values for invalid view %d\n", nr);
return GFX_ERROR;
}
@ -1757,7 +1787,13 @@ int gfxop_overflow_cel(gfx_state_t *state, int nr, int *loop, int *cel) {
int cel_v = *cel;
BASIC_CHECKS(GFX_ERROR);
if (!gfxr_get_view(state->resstate, nr, &loop_v, &cel_v, 0)) {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
gfxr_view_t *testView = _gfx->getView(nr, &loop_v, &cel_v, 0);
delete _gfx;
if (!testView) {
GFXWARN("Attempt to verify loop/cel values for invalid view %d\n", nr);
return GFX_ERROR;
}
@ -1777,7 +1813,13 @@ int gfxop_get_cel_parameters(gfx_state_t *state, int nr, int loop, int cel, int
gfx_pixmap_t *pxm = NULL;
BASIC_CHECKS(GFX_ERROR);
if (!(view = gfxr_get_view(state->resstate, nr, &loop, &cel, 0))) {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
view = _gfx->getView(nr, &loop, &cel, 0);
delete _gfx;
if (!view) {
GFXWARN("Attempt to get cel parameters for invalid view %d\n", nr);
return GFX_ERROR;
}
@ -1799,7 +1841,13 @@ static int _gfxop_draw_cel_buffer(gfx_state_t *state, int nr, int loop, int cel,
int old_x, old_y;
BASIC_CHECKS(GFX_FATAL);
if (!(view = gfxr_get_view(state->resstate, nr, &loop, &cel, palette))) {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
view = _gfx->getView(nr, &loop, &cel, palette);
delete _gfx;
if (!view) {
GFXWARN("Attempt to draw loop/cel %d/%d in invalid view %d\n", loop, cel, nr);
return GFX_ERROR;
}
@ -1868,18 +1916,15 @@ int gfxop_new_pic(gfx_state_t *state, int nr, int flags, int default_palette) {
state->tag_mode = 1;
state->palette_nr = default_palette;
state->pic = _gfx->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, true);
delete _gfx;
if (state->driver->mode->xfact == 1 && state->driver->mode->yfact == 1) {
state->pic_unscaled = state->pic;
} else {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
_gfx = new GfxResManager(state->resstate);
state->pic = _gfx->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false);
delete _gfx;
}
delete _gfx;
if (!state->pic || !state->pic_unscaled) {
GFXERROR("Could not retrieve background pic %d!\n", nr);
if (state->pic) {
@ -1907,12 +1952,19 @@ int gfxop_add_to_pic(gfx_state_t *state, int nr, int flags, int default_palette)
return GFX_ERROR;
}
if (!(state->pic = gfxr_add_to_pic(state->resstate, state->pic_nr, nr, GFX_MASK_VISUAL, flags, state->palette_nr, default_palette, 1))) {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state->resstate);
state->pic = _gfx->addToPic(state->pic_nr, nr, flags, state->palette_nr, default_palette);
if (!state->pic) {
GFXERROR("Could not add pic #%d to pic #%d!\n", state->pic_nr, nr);
delete _gfx;
return GFX_ERROR;
}
state->pic_unscaled = gfxr_add_to_pic(state->resstate, state->pic_nr, nr, GFX_MASK_VISUAL, flags,
state->palette_nr, default_palette, 1);
state->pic_unscaled = _gfx->addToPic(state->pic_nr, nr, flags, state->palette_nr, default_palette);
delete _gfx;
return _gfxop_set_pic(state);
}

View File

@ -48,6 +48,75 @@ struct param_struct {
gfx_driver_t *driver;
};
#define DRAW_PIC01(pic, picStyle, isSci1) \
gfxr_draw_pic01((pic), flags, default_palette, res->size, res->data, (picStyle), res->id, (isSci1), state->static_palette);
#define DRAW_PIC11(pic, picStyle) \
gfxr_draw_pic11((pic), flags, default_palette, res->size, res->data, (picStyle), res->id, state->static_palette);
/* Calculate a picture
** Parameters: (gfx_resstate_t *) state: The resource state, containing options and version information
** (gfxr_pic_t *) scaled_pic: The pic structure that is to be written to
** (gfxr_pic_t *) unscaled_pic: The pic structure the unscaled pic is to be written to,
** or NULL if it isn't needed.
** (int) flags: Pic drawing flags (interpreter dependant)
** (int) default_palette: The default palette to use for pic drawing (interpreter dependant)
** (int) nr: pic resource number
** Returns : (int) GFX_ERROR if the resource could not be found, GFX_OK otherwise
*/
int calculatePic(gfx_resstate_t *state, gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, int flags, int default_palette, int nr) {
Resource *res = state->resManager->findResource(kResourceTypePic, nr, 0);
int need_unscaled = unscaled_pic != NULL;
gfxr_pic0_params_t style, basic_style;
basic_style.line_mode = GFX_LINE_MODE_CORRECT;
basic_style.brush_mode = GFX_BRUSH_MODE_SCALED;
basic_style.pic_port_bounds = state->options->pic_port_bounds;
style.line_mode = state->options->pic0_line_mode;
style.brush_mode = state->options->pic0_brush_mode;
style.pic_port_bounds = state->options->pic_port_bounds;
if (!res || !res->data)
return GFX_ERROR;
if (need_unscaled) {
if (state->version == SCI_VERSION_1_1)
DRAW_PIC11(unscaled_pic, &basic_style)
else
DRAW_PIC01(unscaled_pic, &basic_style, state->version >= SCI_VERSION_01_VGA)
}
if (scaled_pic && scaled_pic->undithered_buffer)
memcpy(scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer, scaled_pic->undithered_buffer_size);
if (state->version == SCI_VERSION_1_1)
DRAW_PIC11(scaled_pic, &style)
else
DRAW_PIC01(scaled_pic, &style, state->version >= SCI_VERSION_01_VGA)
if (state->version < SCI_VERSION_01_VGA) {
if (need_unscaled)
gfxr_remove_artifacts_pic0(scaled_pic, unscaled_pic);
if (!scaled_pic->undithered_buffer)
scaled_pic->undithered_buffer = sci_malloc(scaled_pic->undithered_buffer_size);
memcpy(scaled_pic->undithered_buffer, scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer_size);
gfxr_dither_pic0(scaled_pic, state->options->pic0_dither_mode, state->options->pic0_dither_pattern);
}
// Mark default palettes
if (scaled_pic)
scaled_pic->visual_map->loop = default_palette;
if (unscaled_pic)
unscaled_pic->visual_map->loop = default_palette;
return GFX_OK;
}
gfx_resstate_t *gfxr_new_resource_manager(int version, gfx_options_t *options, gfx_driver_t *driver, ResourceManager *resManager) {
gfx_resstate_t *state = new gfx_resstate_t();
@ -62,6 +131,31 @@ gfx_resstate_t *gfxr_new_resource_manager(int version, gfx_options_t *options, g
return state;
}
int GfxResManager::getOptionsHash(gfx_resource_type_t type) {
switch (type) {
case GFX_RESOURCE_TYPE_VIEW:
// This should never happen
error("getOptionsHash called on a VIEW resource");
case GFX_RESOURCE_TYPE_PIC:
if (_state->version >= SCI_VERSION_01_VGA)
return _state->options->pic_port_bounds.y;
else
return (_state->options->pic0_unscaled) ? 0x10000 : (_state->options->pic0_dither_mode << 12)
| (_state->options->pic0_dither_pattern << 8) | (_state->options->pic0_brush_mode << 4)
| (_state->options->pic0_line_mode);
case GFX_RESOURCE_TYPE_FONT:
case GFX_RESOURCE_TYPE_CURSOR:
return 0;
case GFX_RESOURCE_TYPES_NR:
default:
GFXERROR("Invalid resource type: %d\n", type);
return -1;
}
}
#define FREEALL(freecmd, type) \
if (resource->scaled_data.type) \
freecmd(resource->scaled_data.type); \
@ -99,29 +193,29 @@ void gfxr_free_resource(gfx_resource_t *resource, int type) {
free(resource);
}
void gfxr_free_all_resources(gfx_resstate_t *state) {
void GfxResManager::freeAllResources() {
for (int type = 0; type < GFX_RESOURCE_TYPES_NR; ++type) {
for (IntResMap::iterator iter = state->_resourceMaps[type].begin(); iter != state->_resourceMaps[type].end(); ++iter) {
for (IntResMap::iterator iter = _state->_resourceMaps[type].begin(); iter != _state->_resourceMaps[type].end(); ++iter) {
gfxr_free_resource(iter->_value, type);
iter->_value = 0;
}
}
}
void gfxr_free_resource_manager(gfx_resstate_t *state) {
gfxr_free_all_resources(state);
delete state;
void GfxResManager::freeResManager() {
freeAllResources();
delete _state;
}
void gfxr_free_tagged_resources(gfx_resstate_t *state) {
void GfxResManager::freeTaggedResources() {
// Current heuristics: free tagged views and old pics
IntResMap::iterator iter;
int type;
const int tmp = state->tag_lock_counter;
const int tmp = _state->tag_lock_counter;
type = GFX_RESOURCE_TYPE_VIEW;
for (iter = state->_resourceMaps[type].begin(); iter != state->_resourceMaps[type].end(); ++iter) {
for (iter = _state->_resourceMaps[type].begin(); iter != _state->_resourceMaps[type].end(); ++iter) {
gfx_resource_t *resource = iter->_value;
if (resource) {
@ -135,7 +229,7 @@ void gfxr_free_tagged_resources(gfx_resstate_t *state) {
}
type = GFX_RESOURCE_TYPE_PIC;
for (iter = state->_resourceMaps[type].begin(); iter != state->_resourceMaps[type].end(); ++iter) {
for (iter = _state->_resourceMaps[type].begin(); iter != _state->_resourceMaps[type].end(); ++iter) {
gfx_resource_t *resource = iter->_value;
if (resource) {
@ -148,7 +242,7 @@ void gfxr_free_tagged_resources(gfx_resstate_t *state) {
}
}
state->tag_lock_counter = 0;
_state->tag_lock_counter = 0;
}
#define XLATE_AS_APPROPRIATE(key, entry) \
@ -179,10 +273,9 @@ static gfxr_pic_t *gfxr_pic_xlate_common(gfx_resource_t *res, int maps, int scal
gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_palette, bool scaled) {
gfxr_pic_t *npic = NULL;
gfx_resource_type_t restype = GFX_RESOURCE_TYPE_PIC;
IntResMap &resMap = _state->_resourceMaps[restype];
IntResMap &resMap = _state->_resourceMaps[GFX_RESOURCE_TYPE_PIC];
gfx_resource_t *res = NULL;
int hash = gfxr_interpreter_options_hash(restype, _state->version, _state->options, 0);
int hash = getOptionsHash(GFX_RESOURCE_TYPE_PIC);
int must_post_process_pic = 0;
int need_unscaled = (_state->driver->mode->xfact != 1 || _state->driver->mode->yfact != 1);
@ -196,9 +289,9 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale
if (_state->options->pic0_unscaled) {
need_unscaled = 0;
pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(restype, num), _state->version >= SCI_VERSION_01_VGA);
pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _state->version >= SCI_VERSION_01_VGA);
} else
pic = gfxr_init_pic(_state->driver->mode, GFXR_RES_ID(restype, num), _state->version >= SCI_VERSION_01_VGA);
pic = gfxr_init_pic(_state->driver->mode, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _state->version >= SCI_VERSION_01_VGA);
if (!pic) {
GFXERROR("Failed to allocate scaled pic!\n");
return NULL;
@ -207,14 +300,14 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale
gfxr_clear_pic0(pic, SCI_TITLEBAR_SIZE);
if (need_unscaled) {
unscaled_pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(restype, num), _state->version >= SCI_VERSION_01_VGA);
unscaled_pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _state->version >= SCI_VERSION_01_VGA);
if (!unscaled_pic) {
GFXERROR("Failed to allocate unscaled pic!\n");
return NULL;
}
gfxr_clear_pic0(pic, SCI_TITLEBAR_SIZE);
}
if (gfxr_interpreter_calculate_pic(_state, pic, unscaled_pic, flags, default_palette, num)) {
if (calculatePic(_state, pic, unscaled_pic, flags, default_palette, num)) {
gfxr_free_pic(pic);
if (unscaled_pic)
gfxr_free_pic(unscaled_pic);
@ -222,7 +315,7 @@ 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(restype, num);
res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num);
res->lock_sequence_nr = _state->options->buffer_pics_nr;
resMap[num] = res;
} else {
@ -299,22 +392,20 @@ static void _gfxr_unscale_pixmap_index_data(gfx_pixmap_t *pxm, gfx_mode_t *mode)
pxm->flags &= ~GFX_PIXMAP_FLAG_SCALED_INDEX;
}
gfxr_pic_t *gfxr_add_to_pic(gfx_resstate_t *state, int old_nr, int new_nr, int maps, int flags,
int old_default_palette, int default_palette, int scaled) {
gfx_resource_type_t restype = GFX_RESOURCE_TYPE_PIC;
IntResMap &resMap = state->_resourceMaps[restype];
gfxr_pic_t *GfxResManager::addToPic(int old_nr, int new_nr, int flags, int old_default_palette, int default_palette) {
IntResMap &resMap = _state->_resourceMaps[GFX_RESOURCE_TYPE_PIC];
gfxr_pic_t *pic = NULL;
gfx_resource_t *res = NULL;
int hash = gfxr_interpreter_options_hash(restype, state->version, state->options, 0);
int need_unscaled = !(state->options->pic0_unscaled) && (state->driver->mode->xfact != 1 || state->driver->mode->yfact != 1);
int hash = getOptionsHash(GFX_RESOURCE_TYPE_PIC);
int need_unscaled = !(_state->options->pic0_unscaled) && (_state->driver->mode->xfact != 1 || _state->driver->mode->yfact != 1);
res = resMap.contains(old_nr) ? resMap[old_nr] : NULL;
if (!res || (res->mode != MODE_INVALID && res->mode != hash)) {
// FIXME: the initialization of the GFX resource manager should
// be pushed up, and it shouldn't occur here
GfxResManager *_gfx = new GfxResManager(state);
_gfx->getPic(old_nr, 0, flags, old_default_palette, scaled);
GfxResManager *_gfx = new GfxResManager(_state);
_gfx->getPic(old_nr, 0, flags, old_default_palette, 1);
delete _gfx;
res = resMap.contains(old_nr) ? resMap[old_nr] : NULL;
@ -325,36 +416,34 @@ gfxr_pic_t *gfxr_add_to_pic(gfx_resstate_t *state, int old_nr, int new_nr, int m
}
}
if (state->options->pic0_unscaled) // Unscale priority map, if we scaled it earlier
_gfxr_unscale_pixmap_index_data(res->scaled_data.pic->priority_map, state->driver->mode);
if (_state->options->pic0_unscaled) // Unscale priority map, if we scaled it earlier
_gfxr_unscale_pixmap_index_data(res->scaled_data.pic->priority_map, _state->driver->mode);
if (scaled) {
res->lock_sequence_nr = state->options->buffer_pics_nr;
gfxr_interpreter_calculate_pic(state, res->scaled_data.pic, need_unscaled ? res->unscaled_data.pic : NULL,
// The following two operations are needed when returning scaled maps (which is always the case here)
res->lock_sequence_nr = _state->options->buffer_pics_nr;
calculatePic(_state, 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
if (state->options->pic0_unscaled) // Scale priority map again, if needed
res->scaled_data.pic->priority_map = gfx_pixmap_scale_index_data(res->scaled_data.pic->priority_map, state->driver->mode);
if (_state->options->pic0_unscaled) // Scale priority map again, if needed
res->scaled_data.pic->priority_map = gfx_pixmap_scale_index_data(res->scaled_data.pic->priority_map, _state->driver->mode);
{
int old_ID = get_pic_id(res);
set_pic_id(res, GFXR_RES_ID(restype, new_nr)); // To ensure that our graphical translation optoins work properly
pic = gfxr_pic_xlate_common(res, maps, scaled, 1, state->driver->mode, state->options->pic_xlate_filter, 1, state->options);
set_pic_id(res, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, new_nr)); // To ensure that our graphical translation optoins work properly
pic = gfxr_pic_xlate_common(res, GFX_MASK_VISUAL, 1, 1, _state->driver->mode, _state->options->pic_xlate_filter, 1, _state->options);
set_pic_id(res, old_ID);
}
return pic;
}
gfxr_view_t *gfxr_draw_view11(int id, byte *resource, int size);
gfxr_view_t *gfxr_get_view(gfx_resstate_t *state, int nr, int *loop, int *cel, int palette) {
gfx_resource_type_t restype = GFX_RESOURCE_TYPE_VIEW;
IntResMap &resMap = state->_resourceMaps[restype];
gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) {
IntResMap &resMap = _state->_resourceMaps[GFX_RESOURCE_TYPE_VIEW];
gfx_resource_t *res = NULL;
int hash = gfxr_interpreter_options_hash(restype, state->version, state->options, palette);
int hash = palette;
gfxr_view_t *view = NULL;
gfxr_loop_t *loop_data = NULL;
gfx_pixmap_t *cel_data = NULL;
@ -362,16 +451,43 @@ gfxr_view_t *gfxr_get_view(gfx_resstate_t *state, int nr, int *loop, int *cel, i
res = resMap.contains(nr) ? resMap[nr] : NULL;
if (!res || res->mode != hash) {
view = gfxr_interpreter_get_view(*(state->resManager), nr, palette, state->static_palette, state->version);
if (!view)
Resource *viewRes = _state->resManager->findResource(kResourceTypeView, nr, 0);
if (!viewRes || !viewRes->data)
return NULL;
int resid = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr);
if (_state->version < SCI_VERSION_01)
view = gfxr_draw_view0(resid, viewRes->data, viewRes->size, -1);
else if (_state->version == SCI_VERSION_01)
view = gfxr_draw_view0(resid, viewRes->data, viewRes->size, palette);
else if (_state->version >= SCI_VERSION_01_VGA && _state->version <= SCI_VERSION_1_LATE)
view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, _state->static_palette);
else if (_state->version >= SCI_VERSION_1_1)
view = gfxr_draw_view11(resid, viewRes->data, viewRes->size);
if (_state->version >= SCI_VERSION_01_VGA) {
if (!view->palette) {
view->palette = new Palette(_state->static_palette->size());
view->palette->name = "interpreter_get_view";
}
// Palettize view
for (unsigned i = 0; i < MIN(view->palette->size(), _state->static_palette->size()); i++) {
const PaletteEntry& vc = view->palette->getColor(i);
if (vc.r == 0 && vc.g == 0 && vc.b == 0) {
const PaletteEntry& sc = _state->static_palette->getColor(i);
view->palette->setColor(i, sc.r, sc.g, sc.b);
}
}
}
if (!res) {
res = (gfx_resource_t *)sci_malloc(sizeof(gfx_resource_t));
res->scaled_data.view = NULL;
res->ID = GFXR_RES_ID(restype, nr);
res->lock_sequence_nr = state->tag_lock_counter;
res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr);
res->lock_sequence_nr = _state->tag_lock_counter;
res->mode = hash;
resMap[nr] = res;
} else {
@ -382,7 +498,7 @@ gfxr_view_t *gfxr_get_view(gfx_resstate_t *state, int nr, int *loop, int *cel, i
res->unscaled_data.view = view;
} else {
res->lock_sequence_nr = state->tag_lock_counter; // Update lock counter
res->lock_sequence_nr = _state->tag_lock_counter; // Update lock counter
view = res->unscaled_data.view;
}
@ -422,21 +538,18 @@ gfxr_view_t *gfxr_get_view(gfx_resstate_t *state, int nr, int *loop, int *cel, i
}
if (!cel_data->data) {
gfx_get_res_config(state->options, cel_data);
gfx_xlate_pixmap(cel_data, state->driver->mode, state->options->view_xlate_filter);
gfxr_endianness_adjust(cel_data, state->driver->mode);
gfx_get_res_config(_state->options, cel_data);
gfx_xlate_pixmap(cel_data, _state->driver->mode, _state->options->view_xlate_filter);
gfxr_endianness_adjust(cel_data, _state->driver->mode);
}
return view;
}
gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) {
gfx_resource_type_t restype = GFX_RESOURCE_TYPE_FONT;
IntResMap &resMap = _state->_resourceMaps[restype];
IntResMap &resMap = _state->_resourceMaps[GFX_RESOURCE_TYPE_FONT];
gfx_resource_t *res = NULL;
int hash;
hash = gfxr_interpreter_options_hash(restype, _state->version, _state->options, 0);
int hash = getOptionsHash(GFX_RESOURCE_TYPE_FONT);
res = resMap.contains(num) ? resMap[num] : NULL;
@ -450,7 +563,7 @@ gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) {
if (!res) {
res = (gfx_resource_t *)sci_malloc(sizeof(gfx_resource_t));
res->scaled_data.font = NULL;
res->ID = GFXR_RES_ID(restype, num);
res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_FONT, num);
res->lock_sequence_nr = _state->tag_lock_counter;
res->mode = hash;
resMap[num] = res;
@ -471,10 +584,9 @@ gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) {
}
gfx_pixmap_t *GfxResManager::getCursor(int num) {
gfx_resource_type_t restype = GFX_RESOURCE_TYPE_CURSOR;
IntResMap &resMap = _state->_resourceMaps[restype];
IntResMap &resMap = _state->_resourceMaps[GFX_RESOURCE_TYPE_CURSOR];
gfx_resource_t *res = NULL;
int hash = gfxr_interpreter_options_hash(restype, _state->version, _state->options, 0);
int hash = getOptionsHash(GFX_RESOURCE_TYPE_CURSOR);
res = resMap.contains(num) ? resMap[num] : NULL;
@ -497,7 +609,7 @@ gfx_pixmap_t *GfxResManager::getCursor(int num) {
if (!res) {
res = (gfx_resource_t *)sci_malloc(sizeof(gfx_resource_t));
res->scaled_data.pointer = NULL;
res->ID = GFXR_RES_ID(restype, num);
res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_CURSOR, num);
res->lock_sequence_nr = _state->tag_lock_counter;
res->mode = hash;
resMap[num] = res;

View File

@ -1,162 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
// The interpreter-specific part of the resource manager, for SCI
#include "sci/sci_memory.h"
#include "sci/scicore/resource.h"
#include "sci/gfx/gfx_widgets.h"
#include "sci/gfx/gfx_resmgr.h"
#include "sci/gfx/gfx_options.h"
#include "sci/gfx/font.h"
#include "common/util.h"
namespace Sci {
int gfxr_interpreter_options_hash(gfx_resource_type_t type, int version, gfx_options_t *options, int palette) {
switch (type) {
case GFX_RESOURCE_TYPE_VIEW:
return palette;
case GFX_RESOURCE_TYPE_PIC:
if (version >= SCI_VERSION_01_VGA)
return options->pic_port_bounds.y;
else
return (options->pic0_unscaled) ? 0x10000 : (options->pic0_dither_mode << 12)
| (options->pic0_dither_pattern << 8) | (options->pic0_brush_mode << 4) | (options->pic0_line_mode);
case GFX_RESOURCE_TYPE_FONT:
case GFX_RESOURCE_TYPE_CURSOR:
return 0;
case GFX_RESOURCE_TYPES_NR:
default:
GFXERROR("Invalid resource type: %d\n", type);
return -1;
}
}
int gfxr_interpreter_calculate_pic(gfx_resstate_t *state, gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic,
int flags, int default_palette, int nr) {
ResourceManager& resourceManager = *(state->resManager);
Resource *res = resourceManager.findResource(kResourceTypePic, nr, 0);
int need_unscaled = unscaled_pic != NULL;
gfxr_pic0_params_t style, basic_style;
basic_style.line_mode = GFX_LINE_MODE_CORRECT;
basic_style.brush_mode = GFX_BRUSH_MODE_SCALED;
basic_style.pic_port_bounds = state->options->pic_port_bounds;
style.line_mode = state->options->pic0_line_mode;
style.brush_mode = state->options->pic0_brush_mode;
style.pic_port_bounds = state->options->pic_port_bounds;
if (!res || !res->data)
return GFX_ERROR;
if (state->version >= SCI_VERSION_01_VGA) {
if (need_unscaled) {
if (state->version == SCI_VERSION_1_1)
gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id, state->static_palette);
else
gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id, 1, state->static_palette);
}
if (scaled_pic && scaled_pic->undithered_buffer)
memcpy(scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer, scaled_pic->undithered_buffer_size);
if (state->version == SCI_VERSION_1_1)
gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id, state->static_palette);
else
gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id, state->version, state->static_palette);
} else {
if (need_unscaled)
gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id, 0, state->static_palette);
if (scaled_pic && scaled_pic->undithered_buffer)
memcpy(scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer, scaled_pic->undithered_buffer_size);
gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id, 0, state->static_palette);
if (need_unscaled)
gfxr_remove_artifacts_pic0(scaled_pic, unscaled_pic);
if (!scaled_pic->undithered_buffer)
scaled_pic->undithered_buffer = sci_malloc(scaled_pic->undithered_buffer_size);
memcpy(scaled_pic->undithered_buffer, scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer_size);
gfxr_dither_pic0(scaled_pic, state->options->pic0_dither_mode, state->options->pic0_dither_pattern);
}
// Mark default palettes
if (scaled_pic)
scaled_pic->visual_map->loop = default_palette;
if (unscaled_pic)
unscaled_pic->visual_map->loop = default_palette;
return GFX_OK;
}
void gfxr_palettize_view(gfxr_view_t *view, Palette *source) {
for (unsigned i = 0; i < MIN(view->palette->size(), source->size()); i++) {
const PaletteEntry& vc = view->palette->getColor(i);
if (vc.r == 0 && vc.g == 0 && vc.b == 0) {
const PaletteEntry& sc = source->getColor(i);
view->palette->setColor(i, sc.r, sc.g, sc.b);
}
}
}
gfxr_view_t *gfxr_draw_view11(int id, byte *resource, int size);
gfxr_view_t *gfxr_interpreter_get_view(ResourceManager& resourceManager, int nr, int palette, Palette* staticPalette, int version) {
Resource *res = resourceManager.findResource(kResourceTypeView, nr, 0);
int resid = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr);
gfxr_view_t *result = 0;
if (!res || !res->data)
return NULL;
if (version < SCI_VERSION_01) palette = -1;
if (version <= SCI_VERSION_01)
result = gfxr_draw_view0(resid, res->data, res->size, palette);
else if (version >= SCI_VERSION_01_VGA && version <= SCI_VERSION_1_LATE)
result = gfxr_draw_view1(resid, res->data, res->size, staticPalette);
else if (version >= SCI_VERSION_1_1)
result = gfxr_draw_view11(resid, res->data, res->size);
if (version >= SCI_VERSION_01_VGA) {
if (!result->palette) {
result->palette = new Palette(staticPalette->size());
result->palette->name = "interpreter_get_view";
}
gfxr_palettize_view(result, staticPalette);
}
return result;
}
} // End of namespace Sci

View File

@ -49,7 +49,6 @@ MODULE_OBJS = \
gfx/sci_widgets.o \
gfx/resource/res_cursor.o \
gfx/resource/res_font.o \
gfx/resource/res_manager.o \
gfx/resource/res_pal.o \
gfx/resource/res_pic.o \
gfx/resource/res_view0.o \