void crtc_ega_update(device_t *device, bitmap_t *bitmap, const rectangle *cliprect) { crtc_ega_t *crtc_ega = get_safe_token(device); assert(bitmap != NULL); assert(cliprect != NULL); if (crtc_ega->has_valid_parameters) { UINT16 y; void *param = NULL; assert(crtc_ega->intf != NULL); assert(crtc_ega->intf->update_row != NULL); /* call the set up function if any */ if (crtc_ega->intf->begin_update != NULL) param = crtc_ega->intf->begin_update(device, bitmap, cliprect); if (cliprect->min_y == 0) { /* read the start address at the beginning of the frame */ crtc_ega->current_disp_addr = crtc_ega->disp_start_addr; /* also update the cursor state now */ update_cursor_state(crtc_ega); } /* for each row in the visible region */ for (y = cliprect->min_y; y <= cliprect->max_y; y++) { /* compute the current raster line */ UINT8 ra = y % (crtc_ega->max_ras_addr + 1); /* check if the cursor is visible and is on this scanline */ int cursor_visible = crtc_ega->cursor_state && (ra >= (crtc_ega->cursor_start_ras & 0x1f)) && (ra <= crtc_ega->cursor_end_ras) && (crtc_ega->cursor_addr >= crtc_ega->current_disp_addr) && (crtc_ega->cursor_addr < (crtc_ega->current_disp_addr + ( crtc_ega->horiz_disp + 1 ))); /* compute the cursor X position, or -1 if not visible */ INT8 cursor_x = cursor_visible ? (crtc_ega->cursor_addr - crtc_ega->current_disp_addr) : -1; /* call the external system to draw it */ crtc_ega->intf->update_row(device, bitmap, cliprect, crtc_ega->current_disp_addr, ra, y, crtc_ega->horiz_disp + 1, cursor_x, param); /* update MA if the last raster address */ if (ra == crtc_ega->max_ras_addr) crtc_ega->current_disp_addr = (crtc_ega->current_disp_addr + crtc_ega->horiz_disp + 1) & 0xffff; } /* call the tear down function if any */ if (crtc_ega->intf->end_update != NULL) crtc_ega->intf->end_update(device, bitmap, cliprect, param); } else popmessage("Invalid crtc_ega screen parameters - display disabled!!!"); }
void crtc_ega_device::handle_line_timer() { int new_vsync = m_vsync; m_character_counter = 0; m_cursor_x = -1; /* Check if VSYNC is active */ if ( m_vsync_ff ) { m_vsync_width_counter = ( m_vsync_width_counter + 1 ) & 0x0F; /* Check if we've reached end of VSYNC */ if ( m_vsync_width_counter == m_vert_retr_end ) { m_vsync_ff = 0; new_vsync = FALSE; } } if ( m_raster_counter == m_max_ras_addr ) { m_raster_counter = 0; m_line_address = ( m_line_address + m_horiz_disp + 1 ) & 0xffff; } else { m_raster_counter = ( m_raster_counter + 1 ) & 0x1F; } m_line_counter = ( m_line_counter + 1 ) & 0x3ff; /* Check if we've reached the end of active display */ if ( m_line_counter == m_vert_disp_end ) { m_line_enable_ff = false; } /* Check if VSYNC should be enabled */ if ( m_line_counter == m_vert_retr_start ) { m_vsync_width_counter = 0; m_vsync_ff = 1; new_vsync = TRUE; } /* Check if we have reached the end of the vertical area */ if ( m_line_counter == m_vert_total ) { m_line_counter = 0; m_line_address = m_disp_start_addr; m_line_enable_ff = true; set_vblank( FALSE ); /* also update the cursor state now */ update_cursor_state(); if (m_screen != NULL) m_screen->reset_origin(); } if ( m_line_enable_ff ) { /* Schedule DE off signal change */ m_de_off_timer->adjust(attotime::from_ticks( m_horiz_disp + 1, m_clock )); /* Is cursor visible on this line? */ if ( m_cursor_state && (m_raster_counter >= (m_cursor_start_ras & 0x1f)) && (m_raster_counter <= m_cursor_end_ras) && (m_cursor_addr >= m_line_address) && (m_cursor_addr < (m_line_address + m_horiz_disp + 1)) ) { m_cursor_x = m_cursor_addr - m_line_address; /* Schedule CURSOR ON signal */ m_cur_on_timer->adjust( attotime::from_ticks( m_cursor_x, m_clock ) ); } } /* Schedule HSYNC on signal */ m_hsync_on_timer->adjust( attotime::from_ticks( m_horiz_blank_start, m_clock ) ); /* Set VBlank signal */ if ( m_line_counter == m_vert_disp_end + 1 ) { set_vblank( TRUE ); } /* Schedule our next callback */ m_line_timer->adjust( attotime::from_ticks( m_horiz_char_total + 2, m_clock ) ); /* Set VSYNC and DE signals */ set_vsync( new_vsync ); set_de( m_line_enable_ff ? TRUE : FALSE ); }
void sdl_window_info::update() { osd_ticks_t event_wait_ticks; // adjust the cursor state //sdlwindow_update_cursor_state(machine, window); update_cursor_state(); // if we're visible and running and not in the middle of a resize, draw if (m_target != nullptr) { int tempwidth, tempheight; // see if the games video mode has changed m_target->compute_minimum_size(tempwidth, tempheight); if (osd_dim(tempwidth, tempheight) != m_minimum_dim) { m_minimum_dim = osd_dim(tempwidth, tempheight); if (!this->m_fullscreen) { //Don't resize window without user interaction; //window_resize(blitwidth, blitheight); } else if (video_config.switchres) { osd_dim tmp = this->pick_best_mode(); resize(tmp.width(), tmp.height()); } } if (video_config.waitvsync && video_config.syncrefresh) event_wait_ticks = osd_ticks_per_second(); // block at most a second else event_wait_ticks = 0; if (m_rendered_event.wait(event_wait_ticks)) { const int update = 1; // ensure the target bounds are up-to-date, and then get the primitives render_primitive_list &primlist = *renderer().get_primitives(); // and redraw now // Some configurations require events to be polled in the worker thread downcast< sdl_osd_interface& >(machine().osd()).process_events_buf(); // Check whether window has vector screens { const screen_device *screen = screen_device_iterator(machine().root_device()).byindex(m_index); if ((screen != nullptr) && (screen->screen_type() == SCREEN_TYPE_VECTOR)) renderer().set_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); else renderer().clear_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); } m_primlist = &primlist; // if no bitmap, just fill if (m_primlist == nullptr) { } // otherwise, render with our drawing system else { if( video_config.perftest ) measure_fps(update); else renderer().draw(update); } /* all done, ready for next */ m_rendered_event.set(); } } }
void mc6845_device::handle_line_timer() { int new_vsync = m_vsync; m_character_counter = 0; m_cursor_x = -1; /* Check if VSYNC is active */ if ( m_vsync_ff ) { UINT8 vsync_width = m_supports_vert_sync_width ? (m_sync_width >> 4) & 0x0f : 0; m_vsync_width_counter = ( m_vsync_width_counter + 1 ) & 0x0F; /* Check if we've reached end of VSYNC */ if ( m_vsync_width_counter == vsync_width ) { m_vsync_ff = 0; new_vsync = FALSE; } } // For rudimentary 'interlace and video' support, m_raster_counter increments by 1 rather than the correct 2. // The correct test would be: // if ( m_raster_counter == (MODE_INTERLACE_AND_VIDEO ? m_max_ras_addr + 1 : m_max_ras_addr) ) if ( m_raster_counter == m_max_ras_addr ) { /* Check if we have reached the end of the vertical area */ if ( m_line_counter == m_vert_char_total ) { m_adjust_counter = 0; m_adjust_active = 1; } m_raster_counter = 0; m_line_counter = ( m_line_counter + 1 ) & 0x7F; m_line_address = ( m_line_address + m_horiz_disp ) & 0x3fff; /* Check if we've reached the end of active display */ if ( m_line_counter == m_vert_disp ) { m_line_enable_ff = false; m_current_disp_addr = m_disp_start_addr; } /* Check if VSYNC should be enabled */ if ( m_line_counter == m_vert_sync_pos ) { m_vsync_width_counter = 0; m_vsync_ff = 1; new_vsync = TRUE; } } else { // For rudimentary 'interlace and video' support, m_raster_counter increments by 1 rather than the correct 2. // m_raster_counter = ( m_raster_counter + (MODE_INTERLACE_AND_VIDEO ? 2 : 1) ) & 0x1F; m_raster_counter = ( m_raster_counter + 1 ) & 0x1F; } if ( m_adjust_active ) { /* Check if we have reached the end of a full cycle */ if ( m_adjust_counter == m_vert_total_adj ) { m_adjust_active = 0; m_raster_counter = 0; m_line_counter = 0; m_line_address = m_disp_start_addr; m_line_enable_ff = true; /* also update the cursor state now */ update_cursor_state(); if (m_screen != NULL) m_screen->reset_origin(); } else { m_adjust_counter = ( m_adjust_counter + 1 ) & 0x1F; } } if ( m_line_enable_ff ) { /* Schedule DE off signal change */ m_de_off_timer->adjust(attotime::from_ticks( m_horiz_disp, m_clock )); /* Is cursor visible on this line? */ if ( m_cursor_state && (m_raster_counter >= (m_cursor_start_ras & 0x1f)) && (m_raster_counter <= m_cursor_end_ras) && (m_cursor_addr >= m_line_address) && (m_cursor_addr < (m_line_address + m_horiz_disp)) ) { m_cursor_x = m_cursor_addr - m_line_address; /* Schedule CURSOR ON signal */ m_cur_on_timer->adjust( attotime::from_ticks( m_cursor_x, m_clock ) ); } } /* Schedule HSYNC on signal */ m_hsync_on_timer->adjust( attotime::from_ticks( m_horiz_sync_pos, m_clock ) ); /* Schedule our next callback */ m_line_timer->adjust( attotime::from_ticks( m_horiz_char_total + 1, m_clock ) ); /* Set VSYNC and DE signals */ set_vsync( new_vsync ); set_de( m_line_enable_ff ? TRUE : FALSE ); }