Handle flag for NEGATIVE time; unify time incrementing

This commit is contained in:
Allen Hill
2026-08-13 17:47:31 -07:00
parent 0bef565564
commit 5d6b5f4ce0
2 changed files with 43 additions and 36 deletions
+40 -34
View File
@@ -167,7 +167,7 @@ void CDChanger::handle(const Frame &in, Frame &out) {
track = 1;
mins = 0xff;
secs = 0x7f;
flags2 = 0xc0;
flags2 &= ~NEGATIVE;
generateStatus(out, true, Device::CMD_SW);
media_action(MediaAction::Track_Next);
out.reaction = r_TrackChange;
@@ -175,7 +175,7 @@ void CDChanger::handle(const Frame &in, Frame &out) {
case Track_Seek_Down:
state = SEEKING_TRACK;
// Track down returns to track beginning if in ~middle of song
if (mins == 0 && secs < 5) {
if ((flags2 & NEGATIVE) != 0 || (mins == 0 && secs < 5)) {
if (track > 1)
--track;
else
@@ -185,17 +185,13 @@ void CDChanger::handle(const Frame &in, Frame &out) {
}
mins = 0xff;
secs = 0x7f;
flags2 = 0xc0;
flags2 &= ~NEGATIVE;
generateStatus(out, true, Device::CMD_SW);
out.reaction = r_TrackChange;
break;
case Track_Fast_Forward: {
state |= SEEKING;
secs += TIME_SKIP;
if (secs > 59) {
secs -= 60;
++mins;
}
incrementTime(TIME_SKIP);
generateStatus(out, true, Device::CMD_SW);
media_action(MediaAction::Skip_Forward);
cdtimer_reset(); // Skipped to a whole/round sec; ensure next tick
@@ -205,17 +201,7 @@ void CDChanger::handle(const Frame &in, Frame &out) {
}
case Track_Rewind: {
state |= SEEKING;
if (secs < TIME_SKIP) {
if (mins > 0) {
const uint8_t dif = TIME_SKIP - secs;
secs = 60 - dif;
--mins;
} else {
mins = 0;
secs = 0;
}
} else
secs -= TIME_SKIP;
incrementTime(-TIME_SKIP);
generateStatus(out, true, Device::CMD_SW);
media_action(MediaAction::Skip_Backward);
cdtimer_reset(); // Skipped to a whole/round sec; ensure next tick
@@ -268,8 +254,8 @@ void CDChanger::handle(const Frame &in, Frame &out) {
#pragma GCC diagnostic pop
}
std::unique_ptr<Frame> CDChanger::react(
expected<std::unique_ptr<Frame>, detail::SendError> exp) {
std::unique_ptr<Frame>
CDChanger::react(expected<std::unique_ptr<Frame>, detail::SendError> exp) {
if (!exp) {
if (exp.error().reaction == to_underlying(r_StateReport) &&
@@ -277,7 +263,7 @@ std::unique_ptr<Frame> CDChanger::react(
++failedStatusReports > 1) {
failedStatusReports = 0;
stopPlaying(); // Disable periodic updates if e.g. no-one's
// listening (car was turned off?)
// listening (car was turned off?)
}
} else {
auto out = std::move(exp.value());
@@ -348,7 +334,7 @@ void CDChanger::enable(Frame &out) {
if (secs > TWODIGIT_MAX)
secs = 0;
state = SEEKING | SEEKING_TRACK;
flags2 = 0xc0;
flags2 = 0x80;
generateStatus(out, false, Device::STATUS);
out.reaction = r_StartPlaying;
}
@@ -399,19 +385,40 @@ void CDChanger::setTime(uint8_t min, uint8_t sec) {
secs = sec;
}
void CDChanger::incrementTime() {
// Increment the time by inc_sec (REQUIRES |inc_sec| <= 59).
void CDChanger::incrementTime(int8_t inc_sec) {
// Sentinel values (>TWODIGIT_MAX) mean "no time"; leave them alone until
// setTime() replaces them with a real count.
if (secs > TWODIGIT_MAX)
if (mins > TWODIGIT_MAX)
return;
if (secs == 59) {
secs = 0;
if (mins == TWODIGIT_MAX)
mins = 0;
else
mins++;
} else
secs++;
if ((flags2 & NEGATIVE) != 0)
inc_sec = -inc_sec; // time forward shrinks a negative magnitude
int8_t sum = secs + inc_sec;
if (sum < 0 && mins == 0) {
// Stepped through zero: the display flips sign and counts away from it.
secs = (uint8_t)-sum;
flags2 ^= NEGATIVE;
return;
}
if (sum > 59) {
if (mins == TWODIGIT_MAX) { // saturate at 99:59 rather than wrap the hour
secs = 59;
return;
}
sum -= 60;
++mins;
} else if (sum < 0) {
sum += 60;
--mins; // mins > 0: the mins == 0 borrow was handled above
}
secs = (uint8_t)sum;
// Zero is neither sign, so it must never display as -00:00.
if ((mins | secs) == 0)
flags2 &= ~NEGATIVE;
}
// Used for changed status messages
@@ -439,7 +446,6 @@ void CDChanger::normalizeState() {
secs = 0;
state = PLAYBACK;
flags &= (uint8_t)~(DISK_SCAN | SCAN);
flags2 = 0x80;
}
#ifndef NDEBUG
+3 -2
View File
@@ -39,6 +39,7 @@ public:
REPEAT = 1 << 4,
DISK_SCAN = 1 << 5,
SCAN = 1 << 6,
NEGATIVE = 1 << 6,
};
/// Message state machine
@@ -68,7 +69,7 @@ public:
void disable(Frame &out);
static bool pending();
void emit(Frame &out);
void incrementTime();
void incrementTime(int8_t inc_sec = 1);
bool isPlaying() const;
#ifndef NDEBUG
void media_action(MediaAction action);
@@ -93,7 +94,7 @@ private:
uint8_t mins = 0xFF; // Decimal storage; serialize to BCD
uint8_t secs = 0x7F; // Decimal storage; serialize to BCD
uint8_t flags = 0;
uint8_t flags2 = 0xC0;
uint8_t flags2 = 0x80;
};
} // namespace avclan