void raster_reset(raster_t *raster) { raster_changes_remove_all(raster->changes->background); raster_changes_remove_all(raster->changes->foreground); raster_changes_remove_all(raster->changes->border); raster_changes_remove_all(raster->changes->sprites); raster_changes_remove_all(raster->changes->next_line); raster->changes->have_on_this_line = 0; raster->current_line = 0; raster->xsmooth = raster->ysmooth = 0; raster->sprite_xsmooth = 0; raster->xsmooth_shift_left = 0; raster->xsmooth_shift_right = 0; raster->sprite_xsmooth_shift_right = 0; raster->skip_frame = 0; raster->blank_off = 0; raster->blank_enabled = 0; raster->blank_this_line = 0; raster->open_right_border = 0; raster->open_left_border = 0; raster->border_disable = 0; raster->blank = 0; raster->draw_idle_state = 0; raster->ycounter = 0; raster->video_mode = 0; raster->last_video_mode = -1; }
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); }
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); }