From a48a6ad30e52f52793ba9b09271146f2553a656d Mon Sep 17 00:00:00 2001 From: johndoe123 Date: Thu, 22 Jan 2015 13:06:02 +0100 Subject: BBVS: Implement loading and saving in the air guitar minigame --- engines/bbvs/minigames/bbairguitar.cpp | 113 ++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 3 deletions(-) (limited to 'engines/bbvs/minigames/bbairguitar.cpp') diff --git a/engines/bbvs/minigames/bbairguitar.cpp b/engines/bbvs/minigames/bbairguitar.cpp index 1984dbb0fd..6f198cb42a 100644 --- a/engines/bbvs/minigames/bbairguitar.cpp +++ b/engines/bbvs/minigames/bbairguitar.cpp @@ -22,6 +22,12 @@ #include "bbvs/minigames/bbairguitar.h" +#include "common/savefile.h" +#include "common/translation.h" + +#include "gui/dialog.h" +#include "gui/message.h" + namespace Bbvs { static const char * const kNoteSoundFilenames[] = { @@ -805,7 +811,7 @@ void MinigameBbAirGuitar::update() { } if (_vm->_keyCode == Common::KEYCODE_ESCAPE) { - _gameDone = true; + _gameDone = querySaveModifiedTracks(); return; } @@ -925,7 +931,8 @@ void MinigameBbAirGuitar::afterButtonReleased() { break; case 4: *_currFrameIndex = 1; - // TODO Run load dialog + loadTracks(); + _objects[1].kind = 0; break; case 5: _objects[3].kind = 0; @@ -950,7 +957,8 @@ void MinigameBbAirGuitar::afterButtonReleased() { break; case 12: *_currFrameIndex = 1; - // TODO Run save dialog + saveTracks(); + _objects[2].kind = 0; break; case 13: _objects[4].kind = 0; @@ -1195,4 +1203,103 @@ void MinigameBbAirGuitar::stopNote(int noteNum) { stopSound(2 + _currPatchNum * kNoteSoundFilenamesCount + noteNum); } +bool MinigameBbAirGuitar::getLoadFilename(Common::String &filename) { + // TODO Run dialog and return actual filename + filename = "test.air"; + return true; +} + +bool MinigameBbAirGuitar::getSaveFilename(Common::String &filename) { + // TODO Run dialog and return actual filename + filename = "test.air"; + return true; +} + +bool MinigameBbAirGuitar::querySaveModifiedDialog() { + /* NOTE The original button captions don't fit so shortened variants are used + Original ok button caption: "Yeah, heh, heh, save it!" + Original discard button caption: "Who cares? It sucked!" + */ + GUI::MessageDialog query(_("Hey Beavis - you didn't save that last Jam!"), + _("Save it!"), + _("It sucked!")); + return query.runModal() == GUI::kMessageOK; +} + +bool MinigameBbAirGuitar::querySaveModifiedTracks() { + if (_modified && querySaveModifiedDialog()) { + if (!saveTracks()) + return false; + } + return true; +} + +bool MinigameBbAirGuitar::loadTracks() { + if (_playerMode != 0) + return false; + + if (!querySaveModifiedTracks()) + return false; + + Common::String filename; + if (!getLoadFilename(filename)) + return false; + + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::InSaveFile *stream = saveFileMan->openForLoading(filename); + if (!loadFromStream(stream)) { + Common::String msg = Common::String::format("%s is not a valid Air Guitar file", filename.c_str()); + GUI::MessageDialog dialog(msg); + dialog.runModal(); + } + delete stream; + + return true; +} + +bool MinigameBbAirGuitar::saveTracks() { + if (_playerMode != 0) + return false; + + Common::String filename; + if (!getSaveFilename(filename)) + return false; + + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::OutSaveFile *stream = saveFileMan->openForSaving(filename); + saveToStream(stream); + delete stream; + _modified = false; + + return true; +} + +bool MinigameBbAirGuitar::loadFromStream(Common::ReadStream *stream) { + uint32 magic = stream->readUint32BE(); + if (magic != MKTAG('A', 'I', 'R', 'G')) + return false; + for (uint i = 0; i < kMaxTracks; ++i) { + _track[i].noteNum = stream->readByte(); + _track[i].ticks = stream->readUint16LE(); + } + _trackCount = 0; + _actionTrackPos = 0; + while (_track[_trackCount].noteNum != -1) { + _actionTrackPos += _track[_trackCount].ticks; + ++_trackCount; + } + _totalTrackLength = _actionTrackPos; + _trackIndex = 0; + _currTrackPos = 0; + return true; +} + +void MinigameBbAirGuitar::saveToStream(Common::WriteStream *stream) { + stream->writeUint32BE(MKTAG('A', 'I', 'R', 'G')); + for (uint i = 0; i < kMaxTracks; ++i) { + stream->writeByte(_track[i].noteNum); + stream->writeUint16LE(_track[i].ticks); + } +} + } // End of namespace Bbvs -- cgit v1.2.3 From aa518306b8a82e22806cdb9820a6ac217a06c16f Mon Sep 17 00:00:00 2001 From: johndoe123 Date: Sun, 1 Feb 2015 17:21:34 +0100 Subject: BBVS: Fix out-of-bounds array access in air guitar minigame as reported by Coverity --- engines/bbvs/minigames/bbairguitar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/bbvs/minigames/bbairguitar.cpp') diff --git a/engines/bbvs/minigames/bbairguitar.cpp b/engines/bbvs/minigames/bbairguitar.cpp index 6f198cb42a..26e27a966f 100644 --- a/engines/bbvs/minigames/bbairguitar.cpp +++ b/engines/bbvs/minigames/bbairguitar.cpp @@ -1121,7 +1121,7 @@ void MinigameBbAirGuitar::noteOff(int noteNum) { if (_actionTrackPos + _ticksDelta > 15000) _ticksDelta = 15000 - _actionTrackPos; _track[_trackCount].ticks = _ticksDelta; - if (_trackCount < 2048) + if (_trackCount + 1 < 2048) ++_trackCount; _track[_trackCount].noteNum = -2; _noteStartTime = _vm->_system->getMillis(); -- cgit v1.2.3