Mercurial > repos > blastem
comparison vdp.c @ 1891:179a2ac29f27
Wait to reacquire framebuffer so that switching to UI does not require pushing a new frame if it happens in between bottom and top of display
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 09 Oct 2019 23:06:02 -0700 |
parents | bd60e74fd173 |
children | 55d034719345 |
comparison
equal
deleted
inserted
replaced
1890:7bb4081e9e52 | 1891:179a2ac29f27 |
---|---|
2048 vdp_update_per_frame_debug(context); | 2048 vdp_update_per_frame_debug(context); |
2049 } | 2049 } |
2050 | 2050 |
2051 static void advance_output_line(vdp_context *context) | 2051 static void advance_output_line(vdp_context *context) |
2052 { | 2052 { |
2053 //This function is kind of gross because of the need to deal with vertical border busting via mode changes | |
2053 uint16_t lines_max = context->inactive_start + context->border_bot + context->border_top; | 2054 uint16_t lines_max = context->inactive_start + context->border_bot + context->border_top; |
2054 | |
2055 if (context->output_lines == lines_max) { | |
2056 if (!headless) { | |
2057 render_framebuffer_updated(context->cur_buffer, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER)); | |
2058 context->cur_buffer = context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD; | |
2059 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); | |
2060 } | |
2061 vdp_update_per_frame_debug(context); | |
2062 context->h40_lines = 0; | |
2063 context->frame++; | |
2064 context->output_lines = 0; | |
2065 } else if (context->output_lines && context->vcounter < context->inactive_start && context->vcounter > context->output_lines) { | |
2066 context->output_lines = context->vcounter; | |
2067 } | |
2068 uint32_t output_line = context->vcounter; | 2055 uint32_t output_line = context->vcounter; |
2069 if (!(context->regs[REG_MODE_2] & BIT_MODE_5)) { | 2056 if (!(context->regs[REG_MODE_2] & BIT_MODE_5)) { |
2070 //vcounter increment occurs much later in Mode 4 | 2057 //vcounter increment occurs much later in Mode 4 |
2071 output_line++; | 2058 output_line++; |
2072 } | 2059 } |
2073 if (output_line < context->inactive_start + context->border_bot && context->output_lines > 0) { | 2060 |
2074 output_line = context->output_lines++;//context->border_top + context->vcounter; | 2061 if (context->output_lines == lines_max || (!context->pushed_frame && output_line == context->inactive_start + context->border_top)) { |
2075 } else if (output_line >= 0x200 - context->border_top || (!context->border_top && !output_line)) { | 2062 //we've either filled up a full frame or we're at the bottom of screen in the current defined mode + border crop |
2076 if (output_line == 0x200 - context->border_top || (!context->border_top && !output_line)) { | 2063 if (!headless) { |
2064 render_framebuffer_updated(context->cur_buffer, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER)); | |
2065 uint8_t is_even = context->flags2 & FLAG2_EVEN_FIELD; | |
2066 if (context->vcounter <= context->inactive_start && (context->regs[REG_MODE_4] & BIT_INTERLACE)) { | |
2067 is_even = !is_even; | |
2068 } | |
2069 context->cur_buffer = is_even ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD; | |
2070 context->pushed_frame = 1; | |
2071 context->fb = NULL; | |
2072 } | |
2073 vdp_update_per_frame_debug(context); | |
2074 context->h40_lines = 0; | |
2075 context->frame++; | |
2076 context->output_lines = 0; | |
2077 } | |
2078 | |
2079 if (output_line < context->inactive_start + context->border_bot) { | |
2080 if (context->output_lines) { | |
2081 output_line = context->output_lines++;//context->border_top + context->vcounter; | |
2082 } else if (!output_line && !context->border_top) { | |
2083 //top border is completely cropped so we won't hit the case below | |
2084 output_line = 0; | |
2085 context->output_lines = 1; | |
2086 context->pushed_frame = 0; | |
2087 } else { | |
2088 context->output_lines = output_line + 1; | |
2089 } | |
2090 } else if (output_line >= 0x200 - context->border_top) { | |
2091 if (output_line == 0x200 - context->border_top) { | |
2077 //We're at the top of the display, force context->output_lines to be zero to avoid | 2092 //We're at the top of the display, force context->output_lines to be zero to avoid |
2078 //potential screen rolling if the mode is changed at an inopportune time | 2093 //potential screen rolling if the mode is changed at an inopportune time |
2079 context->output_lines = 0; | 2094 context->output_lines = 0; |
2095 context->pushed_frame = 0; | |
2080 } | 2096 } |
2081 output_line = context->output_lines++;//context->vcounter - (0x200 - context->border_top); | 2097 output_line = context->output_lines++;//context->vcounter - (0x200 - context->border_top); |
2082 } else { | 2098 } else { |
2083 context->output = NULL; | 2099 context->output = NULL; |
2084 return; | 2100 return; |
2101 } | |
2102 if (!context->fb) { | |
2103 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); | |
2085 } | 2104 } |
2086 output_line += context->top_offset; | 2105 output_line += context->top_offset; |
2087 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line); | 2106 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line); |
2088 #ifdef DEBUG_FB_FILL | 2107 #ifdef DEBUG_FB_FILL |
2089 for (int i = 0; i < LINEBUF_SIZE; i++) | 2108 for (int i = 0; i < LINEBUF_SIZE; i++) |
2096 } | 2115 } |
2097 } | 2116 } |
2098 | 2117 |
2099 void vdp_release_framebuffer(vdp_context *context) | 2118 void vdp_release_framebuffer(vdp_context *context) |
2100 { | 2119 { |
2101 render_framebuffer_updated(context->cur_buffer, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER)); | 2120 if (context->fb) { |
2102 context->output = context->fb = NULL; | 2121 render_framebuffer_updated(context->cur_buffer, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER)); |
2122 context->output = context->fb = NULL; | |
2123 } | |
2103 } | 2124 } |
2104 | 2125 |
2105 void vdp_reacquire_framebuffer(vdp_context *context) | 2126 void vdp_reacquire_framebuffer(vdp_context *context) |
2106 { | 2127 { |
2107 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); | |
2108 uint16_t lines_max = context->inactive_start + context->border_bot + context->border_top; | 2128 uint16_t lines_max = context->inactive_start + context->border_bot + context->border_top; |
2109 if (context->output_lines <= lines_max && context->output_lines > 0) { | 2129 if (context->output_lines <= lines_max && context->output_lines > 0) { |
2130 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); | |
2110 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * (context->output_lines - 1 + context->top_offset)); | 2131 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * (context->output_lines - 1 + context->top_offset)); |
2111 } else { | 2132 } else { |
2112 context->output = NULL; | 2133 context->output = NULL; |
2113 } | 2134 } |
2114 } | 2135 } |