mirror of
https://github.com/JaCzekanski/Avocado.git
synced 2024-05-20 04:50:32 -04:00
disc: reworked track handling
getTrackBegin returns the first position of the track, whereas getTrackStart returns index1 of that track That with other smaller bugfixes should play CDDA tracks from the beginning (it was 2 seconds into the track before). Also, pregap wasn't handled properly.
This commit is contained in:
parent
4307af04d3
commit
fab6bd3881
|
@ -28,7 +28,13 @@ void CDROM::handleSector() {
|
|||
if (q.validCrc()) {
|
||||
this->lastQ = q;
|
||||
}
|
||||
readSector++;
|
||||
if (audioStatus == AudioStatus::Forward) {
|
||||
readSector += 5;
|
||||
} else if (audioStatus == AudioStatus::Backward) {
|
||||
readSector -= 5;
|
||||
} else {
|
||||
readSector++;
|
||||
}
|
||||
|
||||
if (trackType == disc::TrackType::AUDIO && stat.play) {
|
||||
if (memcmp(rawSector.data(), sync.data(), sync.size()) == 0) {
|
||||
|
@ -82,12 +88,18 @@ void CDROM::handleSector() {
|
|||
}
|
||||
}
|
||||
|
||||
// Broken :( - gets triggered very soon after track starts playing
|
||||
// in Ridge racer music preview.
|
||||
if (mode.cddaAutoPause) {
|
||||
if (track > previousTrack) {
|
||||
postInterrupt(4);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
stat.play = false; // Pause
|
||||
|
||||
if (verbose) {
|
||||
fmt::print("CDROM: CDDA end of track {}, auto pause\n", track);
|
||||
}
|
||||
}
|
||||
}
|
||||
previousTrack = track;
|
||||
|
@ -298,8 +310,8 @@ void CDROM::handleCommand(uint8_t cmd) {
|
|||
case 0x01: cmdGetstat(); break;
|
||||
case 0x02: cmdSetloc(); break;
|
||||
case 0x03: cmdPlay(); break;
|
||||
// Missing 0x04 cmdForward
|
||||
// Missing 0x05 cmdBackward
|
||||
case 0x04: cmdForward(); break;
|
||||
case 0x05: cmdBackward(); break;
|
||||
case 0x06: cmdReadN(); break;
|
||||
case 0x07: cmdMotorOn(); break;
|
||||
case 0x08: cmdStop(); break;
|
||||
|
@ -337,6 +349,7 @@ void CDROM::handleCommand(uint8_t cmd) {
|
|||
postInterrupt(5);
|
||||
writeResponse(0x11);
|
||||
writeResponse(0x40);
|
||||
if (verbose) fmt::print("CDROM: cmd{:02x} -> ({})\n", cmd, dumpFifo(interruptQueue.peek().response));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace device {
|
|||
namespace cdrom {
|
||||
|
||||
class CDROM {
|
||||
enum class AudioStatus { Stop, Play, Pause, Forward, Backward };
|
||||
union StatusCode {
|
||||
enum class Mode { None, Reading, Seeking, Playing };
|
||||
struct {
|
||||
|
@ -129,12 +130,15 @@ class CDROM {
|
|||
int seekSector = 0;
|
||||
|
||||
StatusCode stat;
|
||||
AudioStatus audioStatus = AudioStatus::Stop;
|
||||
|
||||
int scexCounter = 0;
|
||||
|
||||
void cmdGetstat();
|
||||
void cmdSetloc();
|
||||
void cmdPlay();
|
||||
void cmdForward();
|
||||
void cmdBackward();
|
||||
void cmdReadN();
|
||||
void cmdMotorOn();
|
||||
void cmdStop();
|
||||
|
@ -234,6 +238,7 @@ class CDROM {
|
|||
ar(seekSector);
|
||||
ar(scexCounter);
|
||||
ar(stat._reg);
|
||||
ar(audioStatus);
|
||||
ar(volumeLeftToLeft, volumeLeftToRight, volumeRightToLeft, volumeRightToRight);
|
||||
ar(audio);
|
||||
ar(rawSector);
|
||||
|
|
|
@ -31,30 +31,69 @@ void CDROM::cmdSetloc() {
|
|||
}
|
||||
|
||||
void CDROM::cmdPlay() {
|
||||
disc::Position pos;
|
||||
if (CDROM_params.is_empty() || CDROM_params.peek() == 0) {
|
||||
pos = disc::Position::fromLba(seekSector);
|
||||
} else {
|
||||
int track = bcd::toBinary(readParam()) - 1;
|
||||
if (track >= (int)disc->getTrackCount()) {
|
||||
pos = disc->getTrackStart(disc->getTrackCount() - 1);
|
||||
} else {
|
||||
pos = disc->getTrackStart(track);
|
||||
}
|
||||
if (verbose) fmt::print("CDROM: PLAY (track: {})\n", track + 1);
|
||||
// Too many args
|
||||
if (CDROM_params.size() > 1) {
|
||||
postInterrupt(5);
|
||||
writeResponse(0x01);
|
||||
writeResponse(0x20);
|
||||
return;
|
||||
}
|
||||
|
||||
int trackNo = 0;
|
||||
if (CDROM_params.size() == 1) {
|
||||
trackNo = bcd::toBinary(readParam());
|
||||
}
|
||||
|
||||
disc::Position pos = disc::Position::fromLba(readSector);
|
||||
|
||||
// Start playing track n
|
||||
if (trackNo > 0) {
|
||||
int track = std::min(trackNo - 1, (int)disc->getTrackCount() - 1);
|
||||
pos = disc->getTrackStart(track);
|
||||
|
||||
if (verbose) fmt::print("CDROM: PLAY (track: {}, pos: {})\n", trackNo, pos.toString());
|
||||
} else {
|
||||
if (seekSector != 0) {
|
||||
pos = disc::Position::fromLba(seekSector);
|
||||
seekSector = 0;
|
||||
}
|
||||
|
||||
if (audioStatus == AudioStatus::Pause || audioStatus == AudioStatus::Forward || audioStatus == AudioStatus::Backward) {
|
||||
audioStatus = AudioStatus::Play;
|
||||
} else if (audioStatus == AudioStatus::Play) {
|
||||
} else if (audioStatus == AudioStatus::Stop) {
|
||||
if (seekSector == 0) {
|
||||
pos = disc->getTrackStart(0);
|
||||
}
|
||||
audioStatus = AudioStatus::Play;
|
||||
}
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdPlay (pos: {})\n", pos.toString());
|
||||
}
|
||||
// Too many params - INT5 0x93 0x20
|
||||
|
||||
readSector = pos.toLba();
|
||||
|
||||
stat.setMode(StatusCode::Mode::Playing);
|
||||
|
||||
postInterrupt(3);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
previousTrack = disc->getTrackByPosition(pos);
|
||||
}
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdPlay (pos: {})\n", pos.toString());
|
||||
void CDROM::cmdForward() {
|
||||
audioStatus = AudioStatus::Forward;
|
||||
postInterrupt(3);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdForward -> 0x{:02x}\n", interruptQueue.peek().response[0]);
|
||||
}
|
||||
|
||||
void CDROM::cmdBackward() {
|
||||
audioStatus = AudioStatus::Backward;
|
||||
postInterrupt(3);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdBackward -> 0x{:02x}\n", interruptQueue.peek().response[0]);
|
||||
}
|
||||
|
||||
void CDROM::cmdReadN() {
|
||||
|
@ -88,6 +127,7 @@ void CDROM::cmdMotorOn() {
|
|||
|
||||
void CDROM::cmdStop() {
|
||||
stat.setMode(StatusCode::Mode::None);
|
||||
audioStatus = AudioStatus::Stop;
|
||||
stat.motor = 0;
|
||||
|
||||
postInterrupt(3);
|
||||
|
@ -104,6 +144,7 @@ void CDROM::cmdPause() {
|
|||
writeResponse(stat._reg);
|
||||
|
||||
stat.setMode(StatusCode::Mode::None);
|
||||
audioStatus = AudioStatus::Pause;
|
||||
|
||||
postInterrupt(2);
|
||||
writeResponse(stat._reg);
|
||||
|
@ -188,10 +229,15 @@ void CDROM::cmdSetSession() {
|
|||
|
||||
void CDROM::cmdSeekP() {
|
||||
readSector = seekSector;
|
||||
seekSector = 0;
|
||||
|
||||
auto prevStat = stat;
|
||||
|
||||
stat.setMode(StatusCode::Mode::None);
|
||||
postInterrupt(3);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
stat = prevStat;
|
||||
postInterrupt(2, 500000);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
|
@ -357,7 +403,7 @@ void CDROM::cmdTest() {
|
|||
|
||||
if (verbose) {
|
||||
auto CDROM_response = interruptQueue.peek().response;
|
||||
fmt::print("//CDROM: cmdTest(0x{:02x}) -> ({})\n", opcode, dumpFifo(CDROM_response));
|
||||
fmt::print("CDROM: cmdTest(0x{:02x}) -> ({})\n", opcode, dumpFifo(CDROM_response));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ struct Disc {
|
|||
virtual std::string getFile() const = 0;
|
||||
virtual size_t getTrackCount() const = 0;
|
||||
virtual int getTrackByPosition(Position pos) const = 0;
|
||||
virtual Position getTrackStart(int track) const = 0;
|
||||
virtual Position getTrackBegin(int track) const = 0; // MMSSFF of track first sector
|
||||
virtual Position getTrackStart(int track) const = 0; // MMSSFF of track index1
|
||||
virtual Position getTrackLength(int track) const = 0;
|
||||
virtual Position getDiskSize() const = 0;
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@ struct Empty : public Disc {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Position getTrackBegin(int track) const {
|
||||
(void)track;
|
||||
return Position{0, 0, 0};
|
||||
}
|
||||
|
||||
Position getTrackStart(int track) const {
|
||||
(void)track;
|
||||
return Position{0, 0, 0};
|
||||
|
|
|
@ -127,31 +127,26 @@ int Chd::getTrackByPosition(Position pos) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Position Chd::getTrackStart(int track) const {
|
||||
size_t frames = 0;
|
||||
Position Chd::getTrackBegin(int track) const {
|
||||
size_t frames = 75 * 2;
|
||||
if ((unsigned)track < tracks.size()) {
|
||||
for (int i = 0; i < track - 1; i++) {
|
||||
for (int i = 0; i < track; i++) {
|
||||
frames += tracks[i].frames;
|
||||
}
|
||||
}
|
||||
|
||||
return Position::fromLba(frames) + Position(0, 2, 0);
|
||||
return Position::fromLba(frames);
|
||||
}
|
||||
Position Chd::getTrackStart(int track) const { return getTrackBegin(track) + tracks[track].start(); }
|
||||
|
||||
Position Chd::getTrackLength(int track) const {
|
||||
if ((unsigned)track < tracks.size()) {
|
||||
return Position::fromLba(tracks[track].frames);
|
||||
} else {
|
||||
return Position(0, 2, 0);
|
||||
}
|
||||
}
|
||||
Position Chd::getTrackLength(int track) const { return Position::fromLba(tracks[track].pregap.toLba() + tracks[track].frames); }
|
||||
|
||||
Position Chd::getDiskSize() const {
|
||||
size_t frames = 0;
|
||||
for (size_t i = 0; i < tracks.size(); i++) {
|
||||
frames += tracks[i].frames;
|
||||
size_t frames = 75 * 2;
|
||||
for (auto t : tracks) {
|
||||
frames += t.pregap.toLba() + t.frames;
|
||||
}
|
||||
return Position::fromLba(frames) + Position(0, 2, 0);
|
||||
return Position::fromLba(frames);
|
||||
}
|
||||
} // namespace format
|
||||
} // namespace disc
|
|
@ -18,6 +18,7 @@ struct Chd : public Disc {
|
|||
std::string getFile() const override;
|
||||
size_t getTrackCount() const override;
|
||||
int getTrackByPosition(Position pos) const override;
|
||||
Position getTrackBegin(int track) const override;
|
||||
Position getTrackStart(int track) const override;
|
||||
Position getTrackLength(int track) const override;
|
||||
Position getDiskSize() const override;
|
||||
|
|
|
@ -6,34 +6,33 @@ namespace format {
|
|||
std::string Cue::getFile() const { return file; }
|
||||
|
||||
Position Cue::getDiskSize() const {
|
||||
int frames = 0;
|
||||
size_t frames = 75 * 2;
|
||||
for (auto t : tracks) {
|
||||
frames += t.frames;
|
||||
frames += t.pregap.toLba() + t.frames;
|
||||
}
|
||||
return Position::fromLba(frames) + Position{0, 2, 0};
|
||||
return Position::fromLba(frames);
|
||||
}
|
||||
|
||||
size_t Cue::getTrackCount() const { return tracks.size(); }
|
||||
|
||||
Position Cue::getTrackStart(int track) const {
|
||||
size_t total = 0;
|
||||
if (tracks.at(0).type == disc::TrackType::DATA) {
|
||||
total += 75 * 2;
|
||||
}
|
||||
Position Cue::getTrackBegin(int track) const {
|
||||
size_t total = 75 * 2;
|
||||
for (int i = 0; i < track; i++) {
|
||||
total += tracks.at(i).frames;
|
||||
total += tracks[i].pregap.toLba() + tracks[i].frames;
|
||||
}
|
||||
return Position::fromLba(total);
|
||||
}
|
||||
|
||||
Position Cue::getTrackLength(int track) const { return Position::fromLba(tracks.at(track).frames); }
|
||||
Position Cue::getTrackStart(int track) const { return getTrackBegin(track) + tracks[track].start(); }
|
||||
|
||||
Position Cue::getTrackLength(int track) const { return Position::fromLba(tracks[track].pregap.toLba() + tracks[track].frames); }
|
||||
|
||||
int Cue::getTrackByPosition(Position pos) const {
|
||||
for (size_t i = 0; i < getTrackCount(); i++) {
|
||||
auto start = getTrackStart(i);
|
||||
auto size = tracks[i].frames;
|
||||
auto begin = getTrackBegin(i);
|
||||
auto length = getTrackLength(i);
|
||||
|
||||
if (pos >= start && pos < start + Position::fromLba(size)) {
|
||||
if (pos >= begin && pos < begin + length) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -41,34 +40,34 @@ int Cue::getTrackByPosition(Position pos) const {
|
|||
}
|
||||
|
||||
disc::Sector Cue::read(Position pos) {
|
||||
auto buffer = std::vector<uint8_t>(Track::SECTOR_SIZE);
|
||||
auto type = disc::TrackType::INVALID;
|
||||
|
||||
auto buffer = std::vector<uint8_t>(Track::SECTOR_SIZE, 0);
|
||||
auto trackNum = getTrackByPosition(pos);
|
||||
if (trackNum != -1) {
|
||||
auto track = tracks[trackNum];
|
||||
if (files.find(track.filename) == files.end()) {
|
||||
auto f = unique_ptr_file(fopen(track.filename.c_str(), "rb"));
|
||||
if (!f) {
|
||||
fmt::print("Unable to load file {}\n", track.filename);
|
||||
return std::make_pair(buffer, type);
|
||||
}
|
||||
|
||||
files.emplace(track.filename, std::move(f));
|
||||
}
|
||||
|
||||
type = track.type;
|
||||
auto file = files[track.filename].get();
|
||||
|
||||
if (trackNum == 0 && type == disc::TrackType::DATA) {
|
||||
pos = pos - Position{0, 2, 0};
|
||||
}
|
||||
auto seek = pos - *track.index0;
|
||||
fseek(file, (long)(track.offset + seek.toLba() * Track::SECTOR_SIZE), SEEK_SET);
|
||||
fread(buffer.data(), Track::SECTOR_SIZE, 1, file);
|
||||
if (trackNum == -1) {
|
||||
return std::make_pair(buffer, disc::TrackType::INVALID);
|
||||
}
|
||||
|
||||
return std::make_pair(buffer, type);
|
||||
auto track = tracks[trackNum];
|
||||
if (files.find(track.filename) == files.end()) {
|
||||
auto f = unique_ptr_file(fopen(track.filename.c_str(), "rb"));
|
||||
if (!f) {
|
||||
fmt::print("Unable to load file {}\n", track.filename);
|
||||
return std::make_pair(buffer, disc::TrackType::INVALID);
|
||||
}
|
||||
|
||||
files.emplace(track.filename, std::move(f));
|
||||
}
|
||||
auto file = files[track.filename].get();
|
||||
auto seek = pos - (getTrackBegin(trackNum) + track.pregap);
|
||||
|
||||
long offset = track.offset + seek.toLba() * Track::SECTOR_SIZE;
|
||||
if (offset < 0) { // Pregap
|
||||
return std::make_pair(buffer, track.type);
|
||||
}
|
||||
|
||||
fseek(file, offset, SEEK_SET);
|
||||
fread(buffer.data(), Track::SECTOR_SIZE, 1, file);
|
||||
|
||||
return std::make_pair(buffer, track.type);
|
||||
}
|
||||
|
||||
std::unique_ptr<Cue> Cue::fromBin(const char* file) {
|
||||
|
|
|
@ -22,6 +22,7 @@ struct Cue : public Disc {
|
|||
std::string getFile() const override;
|
||||
Position getDiskSize() const override;
|
||||
size_t getTrackCount() const override;
|
||||
Position getTrackBegin(int track) const override;
|
||||
Position getTrackStart(int track) const override;
|
||||
Position getTrackLength(int track) const override;
|
||||
int getTrackByPosition(Position pos) const override;
|
||||
|
|
|
@ -82,18 +82,8 @@ void CueParser::addTrackToCue() {
|
|||
// ignore if track is not completed
|
||||
if (track.number == 0) return;
|
||||
|
||||
// if (track.number == 1 && track.type == Track::Type::DATA) {
|
||||
// track.pregap = track.pregap + Position{0,2,0};
|
||||
// }
|
||||
|
||||
if (track.pregap == Position{0, 0, 0} && track.index0) {
|
||||
track.pregap = track.index1 - *track.index0;
|
||||
} else {
|
||||
track.index0 = track.index1;
|
||||
}
|
||||
|
||||
if (!track.index0) {
|
||||
track.index0 = track.index1 - track.pregap;
|
||||
track.index0 = track.index1;
|
||||
}
|
||||
|
||||
cue.tracks.push_back(track);
|
||||
|
|
|
@ -11,6 +11,8 @@ disc::Position Ecm::getDiskSize() const { return disc::Position::fromLba(data.si
|
|||
|
||||
size_t Ecm::getTrackCount() const { return 1; }
|
||||
|
||||
disc::Position Ecm::getTrackBegin(int track) const { return disc::Position(0, 2, 0); }
|
||||
|
||||
disc::Position Ecm::getTrackStart(int track) const { return disc::Position(0, 2, 0); }
|
||||
|
||||
disc::Position Ecm::getTrackLength(int track) const { return disc::Position::fromLba(data.size() / Track::SECTOR_SIZE); }
|
||||
|
|
|
@ -21,6 +21,7 @@ struct Ecm : public Disc {
|
|||
std::string getFile() const override;
|
||||
Position getDiskSize() const override;
|
||||
size_t getTrackCount() const override;
|
||||
Position getTrackBegin(int track) const override;
|
||||
Position getTrackStart(int track) const override;
|
||||
Position getTrackLength(int track) const override;
|
||||
int getTrackByPosition(Position pos) const override;
|
||||
|
|
|
@ -13,7 +13,10 @@ Position Position::fromLba(size_t lba) {
|
|||
return Position(mm, ss, ff);
|
||||
}
|
||||
|
||||
std::string Position::toString() const { return fmt::format("{:02d}:{:02d}:{:02d}", mm, ss, ff); }
|
||||
std::string Position::toString() const {
|
||||
bool isNegative = mm < 0 || ss < 0 || ff < 0;
|
||||
return fmt::format("{:02d}:{:02d}:{:02d}", std::abs(mm) * (isNegative ? -1 : 1), std::abs(ss), std::abs(ff));
|
||||
}
|
||||
|
||||
int Position::toLba() const { return (mm * 60 * 75) + (ss * 75) + ff; }
|
||||
|
||||
|
@ -21,6 +24,22 @@ Position Position::operator+(const Position& p) const { return fromLba(toLba() +
|
|||
|
||||
Position Position::operator-(const Position& p) const { return fromLba(toLba() - p.toLba()); }
|
||||
|
||||
Position& Position::operator+=(const Position& p) {
|
||||
auto val = fromLba(toLba() + p.toLba());
|
||||
mm = val.mm;
|
||||
ss = val.ss;
|
||||
ff = val.ff;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Position& Position::operator-=(const Position& p) {
|
||||
auto val = fromLba(toLba() - p.toLba());
|
||||
mm = val.mm;
|
||||
ss = val.ss;
|
||||
ff = val.ff;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Position::operator==(const Position& p) const { return toLba() == p.toLba(); }
|
||||
|
||||
bool Position::operator>=(const Position& p) const { return toLba() >= p.toLba(); }
|
||||
|
|
|
@ -16,6 +16,8 @@ struct Position {
|
|||
int toLba() const;
|
||||
Position operator+(const Position& p) const;
|
||||
Position operator-(const Position& p) const;
|
||||
Position& operator+=(const Position& p);
|
||||
Position& operator-=(const Position& p);
|
||||
bool operator==(const Position& p) const;
|
||||
bool operator>=(const Position& p) const;
|
||||
bool operator<(const Position& p) const;
|
||||
|
|
|
@ -26,5 +26,14 @@ struct Track {
|
|||
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
Position pause() const {
|
||||
if (index0) {
|
||||
return (index1 - *index0);
|
||||
}
|
||||
return Position(0, 0, 0);
|
||||
}
|
||||
|
||||
Position start() const { return pregap + pause(); }
|
||||
};
|
||||
} // namespace disc
|
||||
|
|
|
@ -21,21 +21,23 @@ void Cdrom::cdromWindow(System* sys) {
|
|||
ImGui::Text("%s", cue->file.c_str());
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
ImGui::Text("Track Pregap Start End Offset Type File");
|
||||
ImGui::Text("Track Pregap Pause Start End Length Offset Type File");
|
||||
|
||||
ImGuiListClipper clipper((int)cue->getTrackCount());
|
||||
while (clipper.Step()) {
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||
auto track = cue->tracks[i];
|
||||
|
||||
auto line = fmt::format("{:>5} {:<8} {:<8} {:<8} {:<9} {:<5} {}",
|
||||
i + 1, //
|
||||
POSITION(track.pregap), //
|
||||
POSITION(track.index1), //
|
||||
POSITION(track.index1 + Position::fromLba(track.frames)), //
|
||||
track.offset, //
|
||||
track.type == TrackType::DATA ? "DATA" : "AUDIO", //
|
||||
getFilenameExt(track.filename) //
|
||||
auto line = fmt::format("{:>5} {:<8} {:<8} {:<8} {:<8} {:<8} {:<9} {:<5} {}",
|
||||
i + 1, //
|
||||
POSITION(track.pregap), //
|
||||
POSITION(track.pause()), //
|
||||
POSITION(cue->getTrackStart(i)), //
|
||||
POSITION(cue->getTrackStart(i) + cue->getTrackLength(i) - disc::Position(0, 0, 1)), //
|
||||
POSITION(cue->getTrackLength(i)), //
|
||||
track.offset, //
|
||||
track.type == TrackType::DATA ? "DATA" : "AUDIO", //
|
||||
getFilenameExt(track.filename) //
|
||||
);
|
||||
|
||||
ImGui::Selectable(line.c_str());
|
||||
|
@ -51,4 +53,4 @@ void Cdrom::cdromWindow(System* sys) {
|
|||
void Cdrom::displayWindows(System* sys) {
|
||||
if (cdromWindowOpen) cdromWindow(sys);
|
||||
}
|
||||
} // namespace gui::debug::cdrom
|
||||
} // namespace gui::debug
|
|
@ -20,7 +20,7 @@ namespace state {
|
|||
const char* lastSaveName = "last.state";
|
||||
|
||||
struct StateMetadata {
|
||||
inline static const uint32_t SAVESTATE_VERSION = 6;
|
||||
inline static const uint32_t SAVESTATE_VERSION = 7;
|
||||
|
||||
uint32_t version = SAVESTATE_VERSION;
|
||||
std::string biosPath;
|
||||
|
|
Loading…
Reference in a new issue