Пример #1
0
static void handle_visible_line_without_cache(raster_t *raster)
{
    geometry_t *geometry;
    raster_cache_t *cache;

    geometry = raster->geometry;

    /* If screen is scrolled to the right, we need to fill with the
       background color the blank part on the left.  */

    fill_background(raster);

    /* Draw the graphics and sprites.  */
    raster_modes_draw_line(raster->modes, raster_line_get_real_mode(raster));
    draw_sprites(raster);
    raster_line_draw_borders(raster);

    cache = &raster->cache[raster->current_line];

    if (raster->dont_cache
        || (raster->sprite_status != NULL
        && raster->sprite_status->dma_msk != 0)
        || cache->is_dirty
        || cache->blank
        || cache->border_color != raster->border_color
    /* FIXME: Done differently in another place.  */
        || cache->open_right_border != raster->open_right_border
        || cache->open_left_border != raster->open_left_border
        || cache->idle_background_color != raster->idle_background_color
        || cache->xsmooth_color != raster->xsmooth_color) {
        cache->blank = 0;
        cache->is_dirty = 0;
        cache->border_color = raster->border_color;
        cache->open_right_border = raster->open_right_border;
        cache->open_left_border = raster->open_left_border;
        cache->xsmooth_color = raster->xsmooth_color;
        cache->idle_background_color = raster->idle_background_color;

        add_line_to_area(raster->update_area, map_current_line_to_area(raster),
                         0, raster->geometry->screen_size.width - 1);
    } else {
        /* Still do some minimal caching anyway.  */
        /* Only update the part between the borders.  */
        add_line_to_area(raster->update_area, map_current_line_to_area(raster),
                         geometry->gfx_position.x,
                         geometry->gfx_position.x
                         + geometry->gfx_size.width - 1);
    }
}
Пример #2
0
static void handle_blank_line(raster_t *raster)
{
    if (raster->changes->have_on_this_line) {
        raster_changes_t *border_changes;
        unsigned int i, xs;

        raster_changes_apply_all(raster->changes->background);
        raster_changes_apply_all(raster->changes->foreground);
        raster_changes_apply_all(raster->changes->sprites);

        border_changes = raster->changes->border;

        /* Only draw a blank line if there are border changes. If there
           are no border changes just check for dirty cache.  */
        if (border_changes->count > 0) {
            for (xs = i = 0; i < border_changes->count; i++) {
                unsigned int xe;

                xe = border_changes->actions[i].where;

                if (xs < xe) {
                    raster_line_draw_blank(raster, xs, xe);
                    xs = xe;
                }

                raster_changes_apply(border_changes, i);
            }

            if (xs < raster->geometry->screen_size.width - 1)
                raster_line_draw_blank(raster, xs,
                                       raster->geometry->screen_size.width - 1);

            raster->cache[raster->current_line].border_color = 0xFF;
            raster->cache[raster->current_line].blank = 1;

            raster_changes_remove_all(border_changes);

            add_line_to_area(raster->update_area, map_current_line_to_area(raster),
                             0, raster->geometry->screen_size.width - 1);
        } else {
            handle_blank_line_cached(raster);
        }
        raster->changes->have_on_this_line = 0;
    } else {
        handle_blank_line_cached(raster);
    }

    update_sprite_collisions(raster);
}
Пример #3
0
inline static void handle_blank_line_cached(raster_t *raster)
{
    if (raster->dont_cache
        || raster->cache[raster->current_line].is_dirty
        || raster->border_color
        != raster->cache[raster->current_line].border_color
        || !raster->cache[raster->current_line].blank) {
        /* Even when the actual caching is disabled, redraw blank lines
           only if it is really necessary to do so.  */
        raster->cache[raster->current_line].border_color
            = raster->border_color;
        raster->cache[raster->current_line].blank = 1;
        raster->cache[raster->current_line].is_dirty = 0;

        raster_line_draw_blank(raster, 0,
                               raster->geometry->screen_size.width - 1);
        add_line_to_area(raster->update_area,
                         map_current_line_to_area(raster),
                         0, raster->geometry->screen_size.width - 1);
    }
}
Пример #4
0
static void handle_visible_line_with_changes(raster_t *raster)
{
    unsigned int i;
    int xs, xstop, old_draw_idle_state, old_video_mode;
    geometry_t *geometry;
    raster_changes_all_t *changes;

    geometry = raster->geometry;
    changes = raster->changes;

    /* Idle state is changed in both background and foreground. As background
       changes may change the value, save the original value and restore it
       later before processing the foreground changes.  */
    old_draw_idle_state = raster->draw_idle_state;
    old_video_mode = raster->video_mode;

    /* Draw the background.  */
    for (xs = i = 0; i < changes->background->count; i++) {
        int xe = changes->background->actions[i].where;

        if (xs < xe) {
            raster_modes_draw_background(raster->modes,
                                         raster_line_get_real_mode(raster),
                                         xs,
                                         xe - 1);
            xs = xe;
        }
        raster_changes_apply(changes->background, i);
    }
    if (xs <= (int)geometry->screen_size.width - 1)
        raster_modes_draw_background(raster->modes,
                                     raster_line_get_real_mode(raster),
                                     xs,
                                     geometry->screen_size.width - 1);

    raster->draw_idle_state = old_draw_idle_state;
    raster->video_mode = old_video_mode;

    /* Draw the foreground graphics.  */
    for (xs = i = 0; i < changes->foreground->count; i++) {
        int xe = changes->foreground->actions[i].where;

        if (xs < xe) {
            raster_modes_draw_foreground(raster->modes,
                                         raster_line_get_real_mode(raster),
                                         xs,
                                         xe - 1);
            xs = xe;
        }
        raster->xsmooth_shift_left = 0;
        raster_changes_apply(changes->foreground, i);
    }
    if (xs <= (int)geometry->text_size.width - 1)
        raster_modes_draw_foreground(raster->modes,
                                     raster_line_get_real_mode(raster),
                                     xs,
                                     geometry->text_size.width - 1);

    raster->xsmooth_shift_left = 0;

/* 
    Draw the sprites.

    NOTE: make sure not to draw more than the actually visible part of the line,
    because also only that part will get overdrawn by the border color and
    excessive pixels will show up as artefacts in renderers which rely on the
    offscreen area properly being updated (such as Scale2x and CRT emulation).
*/
#if 0
    draw_sprites(raster);
#else
    xs = 0;
    for (i = 0; i < changes->sprites->count; i++) {
        int xe = changes->sprites->actions[i].where;

        if (xe >= geometry->screen_size.width) {
            xe = geometry->screen_size.width - 1;
        }
        if (xs < xe) {
            draw_sprites_partial(raster, xs, xe - 1);
            xs = xe;
        }
        raster_changes_apply(changes->sprites, i);
    }
    if (xs <= geometry->screen_size.width - 1) {
        draw_sprites_partial(raster, xs, geometry->screen_size.width - 1);
    }
#endif

    /* If this is really a blanked line, draw border over all of the line
       considering border changes */
    if (raster->can_disable_border && ((raster->blank_this_line || raster->blank_enabled) && !raster->open_left_border)) {
        for (xs = i = 0; i < changes->border->count; i++) {
            int xe = changes->border->actions[i].where;

            if (xs < xe) {
                if (!raster->border_disable)
                    raster_line_draw_blank(raster, xs, xe - 1);
                xs = xe;
            }
            raster_changes_apply(changes->border, i);
        }
        if (!raster->border_disable)
            if (xs <= (int)geometry->screen_size.width - 1)
                raster_line_draw_blank(raster, xs, geometry->screen_size.width - 1);
    } else {
        /* Draw left border.  */
        xstop = raster->display_xstart - 1;
        if (!raster->open_left_border) {
            for (xs = i = 0;
                (i < changes->border->count
                && changes->border->actions[i].where <= xstop);
                i++) {
                int xe = changes->border->actions[i].where;

                if (xs < xe) {
        	        if (!raster->border_disable)
                        raster_line_draw_blank(raster, xs, xe - 1);
                    xs = xe;
                }
                raster_changes_apply(changes->border, i);
            }
            if ((!raster->border_disable) && (xs <= xstop))
                raster_line_draw_blank(raster, xs, xstop);
        } else {
            for (i = 0;
                (i < changes->border->count
                && changes->border->actions[i].where <= xstop);
                i++)
                raster_changes_apply(changes->border, i);
        }

        /* Draw right border.  */
        if (!raster->open_right_border) {
            for (;
                (i < changes->border->count
                && (changes->border->actions[i].where
                <= raster->display_xstop));
                i++)
                raster_changes_apply(changes->border, i);
            for (xs = raster->display_xstop;
                i < changes->border->count;
                i++) {
                int xe = changes->border->actions[i].where;

                if (xs < xe) {
                    if (!raster->border_disable)
                        raster_line_draw_blank(raster, xs, xe - 1);
                    xs = xe;
                }
                raster_changes_apply(changes->border, i);
            }
            if (!raster->border_disable)
                if (xs <= (int)geometry->screen_size.width - 1)
                    raster_line_draw_blank(raster, xs, geometry->screen_size.width - 1);
        } else {
            for (i = 0; i < changes->border->count; i++)
                raster_changes_apply(changes->border, i);
        }
    }

    raster_changes_remove_all(changes->foreground);
    raster_changes_remove_all(changes->background);
    raster_changes_remove_all(changes->border);
    raster_changes_remove_all(changes->sprites);
    raster->changes->have_on_this_line = 0;

    /* Do not cache this line at all.  */
    raster->cache[raster->current_line].is_dirty = 1;

    add_line_to_area(raster->update_area, map_current_line_to_area(raster),
                     0, raster->geometry->screen_size.width - 1);
}
Пример #5
0
static void handle_visible_line_with_cache(raster_t *raster)
{
    int needs_update;
    unsigned int changed_start, changed_end;
    raster_cache_t *cache;

    cache = &raster->cache[raster->current_line];

    /* Check for "major" changes first.  If there is any, just write straight
       to the cache without any comparisons and redraw the whole line.  */
    /* check_for_major_changes_and_update() is embedded here because of some
       VAC++ bug.  */
    {
        unsigned int video_mode;
        int line;

        video_mode = raster_line_get_real_mode(raster);

        line = raster->current_line - raster->geometry->gfx_position.y
            - raster->ysmooth - 1;

        if (cache->is_dirty
            || raster->dont_cache
            || cache->n != line
            || cache->xsmooth != raster->xsmooth
            || cache->video_mode != video_mode
            || cache->blank
            || cache->ycounter != raster->ycounter
            || cache->border_color != raster->border_color
            || cache->display_xstart != raster->display_xstart
            || cache->display_xstop != raster->display_xstop
            || (cache->open_right_border && !raster->open_right_border)
            || (cache->open_left_border && !raster->open_left_border)
            || cache->xsmooth_color != raster->xsmooth_color
            || cache->idle_background_color
            != raster->idle_background_color) {

            unsigned int changed_start_char, changed_end_char;
            int r;

            cache->n = line;
            cache->xsmooth = raster->xsmooth;
            cache->video_mode = video_mode;
            cache->blank = 0;
            cache->ycounter = raster->ycounter;
            cache->border_color = raster->border_color;
            cache->display_xstart = raster->display_xstart;
            cache->display_xstop = raster->display_xstop;
            cache->open_right_border = raster->open_right_border;
            cache->open_left_border = raster->open_left_border;
            cache->xsmooth_color = raster->xsmooth_color;
            cache->idle_background_color = raster->idle_background_color;

            /* Fill the space between the border and the graphics with the
             background color (necessary if `xsmooth' is != 0).  */

            fill_background(raster);

            if (raster->sprite_status != NULL)
                (raster->fill_sprite_cache)(raster, cache,
                                            &changed_start_char,
                                            &changed_end_char);

            r = raster_modes_fill_cache(raster->modes,
                                        video_mode,
                                        cache,
                                        &changed_start_char,
                                        &changed_end_char, 1);

            /* [ `changed_start' ; `changed_end' ] now covers the whole line, as
             we have called fill_cache() with `1' as the last parameter (no
             check).  */
            raster_modes_draw_line_cached(raster->modes, video_mode,
                                          cache,
                                          changed_start_char,
                                          changed_end_char);

            if (raster->sprite_status != NULL)
                (raster->draw_sprites_when_cache_enabled)(raster, cache);

            changed_start = 0;
            changed_end = raster->geometry->screen_size.width - 1;

            raster_line_draw_borders(raster);

            needs_update = 1;
        } else {
            needs_update = 0;
        }
    }

    if (!needs_update) {
        /* There are no `major' changes: try to do some optimization.  */
        needs_update = update_for_minor_changes(raster,
                                                &changed_start,
                                                &changed_end);
    }

    if (needs_update) {
        add_line_to_area(raster->update_area, map_current_line_to_area(raster),
                         changed_start, changed_end);
    }

    cache->is_dirty = 0;
}