summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2017-06-15 09:45:21 -0700
committerMichael Pavone <pavone@retrodev.com>2017-06-15 09:45:21 -0700
commitdee43c24fbd5f0ee0b81cc325164903c8b25ea1d (patch)
treead8562d7a5d411430122ac75b1e755e571907684
parentfd0dfe77e0c947e63026c944b94675018834351b (diff)
Properly release and reacquire framebuffer pointer when switching contexts. Hopefully fixes the LOCKRECT issue some people are seeing with the SDL 2 fallback renderer
-rw-r--r--genesis.c2
-rw-r--r--sms.c10
-rw-r--r--vdp.c19
-rw-r--r--vdp.h2
4 files changed, 32 insertions, 1 deletions
diff --git a/genesis.c b/genesis.c
index 391cbd6..aee7015 100644
--- a/genesis.c
+++ b/genesis.c
@@ -896,6 +896,7 @@ static void handle_reset_requests(genesis_context *gen)
//Is there any sort of VDP reset?
m68k_reset(gen->m68k);
}
+ vdp_release_framebuffer(gen->vdp);
}
static void start_genesis(system_header *system, char *statefile)
@@ -931,6 +932,7 @@ static void resume_genesis(system_header *system)
genesis_context *gen = (genesis_context *)system;
map_all_bindings(&gen->io);
render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
+ vdp_reacquire_framebuffer(gen->vdp);
resume_68k(gen->m68k);
handle_reset_requests(gen);
}
diff --git a/sms.c b/sms.c
index 74df8b0..9d1ac49 100644
--- a/sms.c
+++ b/sms.c
@@ -226,10 +226,18 @@ static void run_sms(system_header *system)
target_cycle -= adjust;
}
}
+ vdp_release_framebuffer(sms->vdp);
sms->should_return = 0;
render_enable_ym();
}
+static void resume_sms(system_header *system)
+{
+ sms_context *sms = (sms_context *)system;
+ vdp_reacquire_framebuffer(sms->vdp);
+ run_sms(system);
+}
+
static void start_sms(system_header *system, char *statefile)
{
sms_context *sms = (sms_context *)system;
@@ -361,7 +369,7 @@ sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t for
sms->header.set_speed_percent = set_speed_percent;
sms->header.start_context = start_sms;
- sms->header.resume_context = run_sms;
+ sms->header.resume_context = resume_sms;
sms->header.load_save = load_save;
sms->header.persist_save = persist_save;
sms->header.free_context = free_sms;
diff --git a/vdp.c b/vdp.c
index 3b8538e..d5bfefa 100644
--- a/vdp.c
+++ b/vdp.c
@@ -1761,6 +1761,25 @@ static void advance_output_line(vdp_context *context)
}
}
+void vdp_release_framebuffer(vdp_context *context)
+{
+ render_framebuffer_updated(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN: FRAMEBUFFER_ODD, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER));
+ context->output = context->fb = NULL;
+}
+
+void vdp_reacquire_framebuffer(vdp_context *context)
+{
+ context->fb = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch);
+ uint16_t lines_max = (context->flags2 & FLAG2_REGION_PAL)
+ ? 240 + BORDER_TOP_V30_PAL + BORDER_BOT_V30_PAL
+ : 224 + BORDER_TOP_V28 + BORDER_BOT_V28;
+ if (context->output_lines <= lines_max && context->output_lines > 0) {
+ context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * (context->output_lines - 1));
+ } else {
+ context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * INVALID_LINE);
+ }
+}
+
static void render_border_garbage(vdp_context *context, uint32_t address, uint8_t *buf, uint8_t buf_off, uint16_t col)
{
uint8_t base = col >> 9 & 0x30;
diff --git a/vdp.h b/vdp.h
index 0a1bbb5..6c805c2 100644
--- a/vdp.h
+++ b/vdp.h
@@ -248,5 +248,7 @@ uint32_t vdp_cycles_to_frame_end(vdp_context * context);
void write_cram(vdp_context * context, uint16_t address, uint16_t value);
void vdp_check_update_sat_byte(vdp_context *context, uint32_t address, uint8_t value);
void vdp_pbc_pause(vdp_context *context);
+void vdp_release_framebuffer(vdp_context *context);
+void vdp_reacquire_framebuffer(vdp_context *context);
#endif //VDP_H_