Mercurial > repos > blastem
changeset 2707:a64c0e1ed6ac default tip
Implement speed control and reset for media player. Fix other bindings that could cause it to crash
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 06 Jul 2025 20:43:37 -0700 |
parents | 0bd48217941a |
children | |
files | bindings.c mediaplayer.c mediaplayer.h |
diffstat | 3 files changed, 83 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/bindings.c Sun Jul 06 20:09:32 2025 -0700 +++ b/bindings.c Sun Jul 06 20:43:37 2025 -0700 @@ -354,7 +354,7 @@ } break; case UI_LOAD_STATE: - if (allow_content_binds) { + if (allow_content_binds && current_system->load_state) { current_system->load_state(current_system, QUICK_SAVE_SLOT); } break; @@ -478,27 +478,6 @@ case UI_CD_GRAPHICS_DEBUG: if (allow_content_binds && current_system->toggle_debug_view) { current_system->toggle_debug_view(current_system, binding->subtype_a - UI_PLANE_DEBUG + DEBUG_PLANE); - /* - vdp_context *vdp = NULL; - if (current_system->type == SYSTEM_GENESIS || current_system->type == SYSTEM_SEGACD) { - genesis_context *gen = (genesis_context *)current_system; - vdp = gen->vdp; - } else if (current_system->type == SYSTEM_SMS) { - sms_context *sms = (sms_context *)current_system; - vdp = sms->vdp; - } - if (vdp) { - uint8_t debug_type; - switch(binding->subtype_a) - { - case UI_PLANE_DEBUG: debug_type = VDP_DEBUG_PLANE; break; - case UI_VRAM_DEBUG: debug_type = VDP_DEBUG_VRAM; break; - case UI_CRAM_DEBUG: debug_type = VDP_DEBUG_CRAM; break; - case UI_COMPOSITE_DEBUG: debug_type = VDP_DEBUG_COMPOSITE; break; - default: return; - } - vdp_toggle_debug_view(vdp, debug_type); - }*/ break; } case UI_PASTE:
--- a/mediaplayer.c Sun Jul 06 20:09:32 2025 -0700 +++ b/mediaplayer.c Sun Jul 06 20:43:37 2025 -0700 @@ -45,6 +45,11 @@ } } +void ym_adjust_clock(chip_info *chip, uint32_t percent) +{ + ym_adjust_master_clock(chip->context, chip->clock * percent / 100); +} + void ym_scope(chip_info *chip, oscilloscope *scope) { ym_enable_scope(chip->context, scope, chip->clock); @@ -77,6 +82,11 @@ } } +void psg_adjust_clock(chip_info *chip, uint32_t percent) +{ + psg_adjust_master_clock(chip->context, chip->clock * percent / 100); +} + void psg_scope(chip_info *chip, oscilloscope *scope) { psg_enable_scope(chip->context, scope, chip->clock); @@ -98,6 +108,11 @@ } } +void pcm_adjust_clock(chip_info *chip, uint32_t percent) +{ + rf5c164_adjust_master_clock(chip->context, chip->clock * percent / 100); +} + void pcm_scope(chip_info *chip, oscilloscope *scope) { rf5c164_enable_scope(chip->context, scope); @@ -691,15 +706,20 @@ return; } +static void wave_stop(media_player *player) +{ + player->current_offset = player->wave->format_header.size + offsetof(wave_header, audio_format); + player->state = STATE_PAUSED; + player->playback_time = 0; +} + void wave_frame(media_player *player) { for (uint32_t remaining_samples = player->wave->sample_rate / 60; remaining_samples > 0; remaining_samples--) { uint32_t sample_size = player->wave->bits_per_sample * player->wave->num_channels / 8; if (sample_size > player->media->size || player->current_offset > player->media->size - sample_size) { - player->current_offset = player->wave->format_header.size + offsetof(wave_header, audio_format); - player->state = STATE_PAUSED; - player->playback_time = 0; + wave_stop(player); return; } if (player->wave->bits_per_sample == 16) { @@ -725,6 +745,13 @@ } } +static void flac_stop(media_player *player) +{ + player->state = STATE_PAUSED; + player->playback_time = 0; + flac_seek(player->flac, 0); +} + void flac_frame(media_player *player) { for (uint32_t remaining_samples = player->flac->sample_rate / 60; remaining_samples > 0; remaining_samples--) @@ -733,8 +760,7 @@ if (flac_get_sample(player->flac, samples, 2)) { render_put_stereo_sample(player->audio, samples[0], samples[1]); } else { - player->state = STATE_PAUSED; - player->playback_time = 0; + flac_stop(player); return; } } @@ -785,6 +811,7 @@ .context = ym, .run = (chip_run_fun)ym_run, .adjust = ym_adjust, + .adjust_clock = ym_adjust_clock, .scope = ym_scope, .no_scope = ym_no_scope, .free = (chip_noarg_fun)ym_free, @@ -803,6 +830,7 @@ .context = psg, .run = (chip_run_fun)psg_run, .adjust = psg_adjust, + .adjust_clock = psg_adjust_clock, .scope = psg_scope, .no_scope = ym_no_scope, .free = (chip_noarg_fun)psg_free, @@ -820,6 +848,7 @@ .context = pcm, .run = (chip_run_fun)rf5c164_run, .adjust = pcm_adjust, + .adjust_clock = pcm_adjust_clock, .scope = pcm_scope, .no_scope = pcm_no_scope, .free = pcm_free, @@ -837,6 +866,7 @@ .context = pcm, .run = (chip_run_fun)rf5c164_run, .adjust = pcm_adjust, + .adjust_clock = pcm_adjust_clock, .scope = pcm_scope, .no_scope = pcm_no_scope, .free = pcm_free, @@ -1027,16 +1057,61 @@ #endif } +static void inc_debug_mode(system_header * system) +{ +} + +static void soft_reset(system_header * system) +{ + media_player *player = (media_player *)system; + switch(player->media_type) + { + case AUDIO_VGM: + vgm_stop(player); + break; + case AUDIO_WAVE: + wave_stop(player); + break; + case AUDIO_FLAC: + flac_stop(player); + break; + } + player->state = STATE_PLAY; +} + +static void set_speed_percent(system_header * system, uint32_t percent) +{ + media_player *player = (media_player *)system; + switch(player->media_type) + { + case AUDIO_VGM: + for (uint32_t i = 0; i < player->num_chips; i++) + { + player->chips[i].adjust_clock(player->chips + i, percent); + } + break; + case AUDIO_WAVE: + render_audio_adjust_clock(player->audio, player->wave->sample_rate * percent / 100, 1); + break; + case AUDIO_FLAC: + render_audio_adjust_clock(player->audio, player->wave->sample_rate * percent / 100, 1); + break; + } +} + media_player *alloc_media_player(system_media *media, uint32_t opts) { media_player *player = calloc(1, sizeof(media_player)); player->header.start_context = start_player; player->header.resume_context = resume_player; player->header.request_exit = request_exit; + player->header.soft_reset = soft_reset; player->header.free_context = free_player; + player->header.set_speed_percent = set_speed_percent; player->header.gamepad_down = gamepad_down; player->header.gamepad_up = gamepad_up; player->header.toggle_debug_view = toggle_debug_view; + player->header.inc_debug_mode = inc_debug_mode; player->header.type = SYSTEM_MEDIA_PLAYER; player->header.info.name = strdup(media->name);
--- a/mediaplayer.h Sun Jul 06 20:09:32 2025 -0700 +++ b/mediaplayer.h Sun Jul 06 20:43:37 2025 -0700 @@ -15,11 +15,13 @@ typedef void (*chip_scope_fun)(chip_info *chip, oscilloscope *scope); typedef void (*chip_noarg_fun)(void *context); typedef void (*chip_adjust_fun)(chip_info *chip); +typedef void (*chip_clock_fun)(chip_info *chip, uint32_t percent); typedef void (*chip_stream_fun)(chip_info *chip, uint8_t port, uint8_t command, uint16_t sample); struct chip_info { void *context; chip_run_fun run; chip_adjust_fun adjust; + chip_clock_fun adjust_clock; chip_scope_fun scope; chip_noarg_fun no_scope; chip_noarg_fun free;