Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/SDK/playback_control.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/SDK/playback_control.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,141 @@ +#include "foobar2000-sdk-pch.h" +#include "playback_control.h" +#include "titleformat.h" + +static double parseFraction(const char * fraction) { + unsigned v = 0, d = 1; + while(pfc::char_is_numeric( *fraction) ) { + d *= 10; + v *= 10; + v += (unsigned) ( *fraction - '0' ); + ++fraction; + } + PFC_ASSERT( *fraction == 0 ); + return (double)v / (double)d; +} + +static double parse_time(const char * time) { + unsigned vTotal = 0, vCur = 0; + for(;;) { + char c = *time++; + if (c == 0) return (double) (vTotal + vCur); + else if (pfc::char_is_numeric( c ) ) { + vCur = vCur * 10 + (unsigned)(c-'0'); + } else if (c == ':') { + if (vCur >= 60) {PFC_ASSERT(!"Invalid input"); return 0; } + vTotal += vCur; vCur = 0; vTotal *= 60; + } else if (c == '.') { + return (double) (vTotal + vCur) + parseFraction(time); + } else { + PFC_ASSERT(!"Invalid input"); return 0; + } + } +} + +double playback_control::playback_get_length() +{ + double rv = 0; + metadb_handle_ptr ptr; + if (get_now_playing(ptr)) + { + rv = ptr->get_length(); + } + return rv; +} + +double playback_control::playback_get_length_ex() { + double rv = 0; + metadb_handle_ptr ptr; + if (get_now_playing(ptr)) + { + rv = ptr->get_length(); + if (rv <= 0) { + pfc::string8 temp; + titleformat_object::ptr script; + titleformat_compiler::get()->compile_force(script, "[%length_ex%]"); + this->playback_format_title(NULL, temp, script, NULL, display_level_titles); + if (temp.length() > 0) rv = parse_time(temp); + } + } + return rv; +} + + + + + + +void playback_control::userPrev() { + userActionHook(); + if (this->is_playing() && this->playback_can_seek() && this->playback_get_position() > 5) { + this->playback_seek(0); + } else { + this->previous(); + } +} + +void playback_control::userNext() { + userActionHook(); + this->start(track_command_next); +} + +void playback_control::userMute() { + userActionHook(); + this->volume_mute_toggle(); +} + +void playback_control::userStop() { + userActionHook(); + this->stop(); +} + +void playback_control::userPlay() { + userActionHook(); + this->play_or_pause(); +} + +void playback_control::userPause() { + userActionHook(); + nonUserPause(); +} + +void playback_control::nonUserPause() { + if (this->is_playing()) { + this->pause(true); + } +} + +void playback_control::userStart() { + userActionHook(); + if (this->is_playing()) { + this->pause(false); + } else { + this->start(); + } +} +static const double seekDelta = 30; +void playback_control::userFastForward() { + userActionHook(); + if (!this->playback_can_seek()) { + this->userNext(); return; + } + this->playback_seek_delta(seekDelta); +} + +void playback_control::userRewind() { + userActionHook(); + if (!this->playback_can_seek()) { + this->userPrev(); return; + } + double p = this->playback_get_position(); + if (p < 0) return; + if (p < seekDelta) { + if (p < seekDelta / 3) { + this->userPrev(); + } else { + this->playback_seek(0); + } + } else { + this->playback_seek_delta(-30); + } +}
