aboutsummaryrefslogtreecommitdiff
path: root/engines/bbvs/minigames/bbairguitar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/bbvs/minigames/bbairguitar.cpp')
-rw-r--r--engines/bbvs/minigames/bbairguitar.cpp1198
1 files changed, 1198 insertions, 0 deletions
diff --git a/engines/bbvs/minigames/bbairguitar.cpp b/engines/bbvs/minigames/bbairguitar.cpp
new file mode 100644
index 0000000000..2c97bcd6bc
--- /dev/null
+++ b/engines/bbvs/minigames/bbairguitar.cpp
@@ -0,0 +1,1198 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "bbvs/minigames/bbairguitar.h"
+
+namespace Bbvs {
+
+static const char * const kNoteSoundFilenames[] = {
+ "a.aif", "a#.aif", "b.aif", "c.aif", "c#.aif",
+ "d.aif", "d#.aif", "e.aif", "f.aif", "f#.aif",
+ "g.aif", "g#.aif", "a_oct.aif"
+};
+
+static const uint kNoteSoundFilenamesCount = ARRAYSIZE(kNoteSoundFilenames);
+
+static const char * const kPatchDirectories[] = {
+ "rock", "burp", "fart"
+};
+
+static const uint kPatchDirectoriesCount = ARRAYSIZE(kPatchDirectories);
+
+static const BBPoint kPianoKeyArea1[] = {{29, 192}, {38, 192}, {38, 222}, {41, 222}, {41, 239}, {29, 239}};
+static const BBPoint kPianoKeyArea2[] = {{38, 192}, {43, 192}, {43, 222}, {38, 222}};
+static const BBPoint kPianoKeyArea3[] = {{43, 192}, {49, 192}, {49, 222}, {52, 222}, {52, 239}, {41, 239}, {41, 222}, {43, 222}};
+static const BBPoint kPianoKeyArea4[] = {{49, 192}, {54, 192}, {54, 222}, {49, 222}};
+static const BBPoint kPianoKeyArea5[] = {{54, 192}, {63, 192}, {63, 239}, {52, 239}, {52, 222}, {54, 222}};
+static const BBPoint kPianoKeyArea6[] = {{63, 192}, {71, 192}, {71, 222}, {74, 222}, {74, 239}, {63, 239}};
+static const BBPoint kPianoKeyArea7[] = {{71, 192}, {76, 192}, {76, 222}, {71, 222}};
+static const BBPoint kPianoKeyArea8[] = {{76, 192}, {82, 192}, {82, 222}, {85, 222}, {85, 239}, {74, 239}, {74, 222}, {76, 222}};
+static const BBPoint kPianoKeyArea9[] = {{82, 192}, {87, 192}, {87, 222}, {82, 222}};
+static const BBPoint kPianoKeyArea10[] = {{87, 192}, {94, 192}, {94, 222}, {96, 222}, {96, 239}, {85, 239}, {85, 222}, {87, 222}};
+static const BBPoint kPianoKeyArea11[] = {{94, 192}, {99, 192}, {99, 222}, {94, 222}};
+static const BBPoint kPianoKeyArea12[] = {{99, 192}, {107, 192}, {107, 239}, {96, 239}, {96, 222}, {99, 222}};
+static const BBPoint kPianoKeyArea13[] = {{107, 192}, {118, 192}, {118, 239}, {107, 239}};
+
+static const BBPolygon kPianoKeyAreas[] = {
+ {kPianoKeyArea1, ARRAYSIZE(kPianoKeyArea1)},
+ {kPianoKeyArea2, ARRAYSIZE(kPianoKeyArea2)},
+ {kPianoKeyArea3, ARRAYSIZE(kPianoKeyArea3)},
+ {kPianoKeyArea4, ARRAYSIZE(kPianoKeyArea4)},
+ {kPianoKeyArea5, ARRAYSIZE(kPianoKeyArea5)},
+ {kPianoKeyArea6, ARRAYSIZE(kPianoKeyArea6)},
+ {kPianoKeyArea7, ARRAYSIZE(kPianoKeyArea7)},
+ {kPianoKeyArea8, ARRAYSIZE(kPianoKeyArea8)},
+ {kPianoKeyArea9, ARRAYSIZE(kPianoKeyArea9)},
+ {kPianoKeyArea10, ARRAYSIZE(kPianoKeyArea10)},
+ {kPianoKeyArea11, ARRAYSIZE(kPianoKeyArea11)},
+ {kPianoKeyArea12, ARRAYSIZE(kPianoKeyArea12)},
+ {kPianoKeyArea13, ARRAYSIZE(kPianoKeyArea13)},
+};
+
+static const BBPoint kObjPoints[] = {
+ {161, 189}, {269, 189}, {161, 208}, {279, 208}, {172, 208},
+ {141, 224}, {257, 191}, {257, 199}, {148, 223}, {124, 224},
+ { 29, 192}, {182, 220}, {245, 220}, {269, 220}, {161, 220},
+ {203, 220}, {224, 220}, {123, 189}, {123, 199}, {123, 209},
+ {134, 224}, { 29, 185}, {124, 224}, {226, 127}, {226, 127},
+ {209, 141}, {244, 141}, {226, 127}, { 99, 107}, { 99, 107},
+ { 76, 137}, {118, 136}, { 99, 107}, {195, 104}, {100, 78}
+};
+
+static const MinigameBbAirGuitar::PianoKeyInfo kPianoKeyInfos[] = {
+ { 30, 192, 0},
+ { 38, 192, 5},
+ { 41, 192, 1},
+ { 49, 192, 5},
+ { 52, 192, 2},
+ { 63, 192, 3},
+ { 71, 192, 5},
+ { 74, 192, 1},
+ { 82, 192, 5},
+ { 85, 192, 1},
+ { 94, 192, 5},
+ { 96, 192, 2},
+ {107, 192, 4}
+};
+
+static const Rect kRect2 = {29, 189, 290, 239};
+static const Rect kPianoRect = {29, 192, 118, 239};
+
+static const Rect kPlayerButtonRects[] = {
+ {123, 189, 145, 199},
+ {123, 199, 145, 209},
+ {123, 209, 145, 220},
+ {148, 223, 156, 236},
+ {161, 189, 182, 205},
+ {161, 208, 171, 218},
+ {161, 220, 182, 231},
+ {182, 220, 203, 231},
+ {203, 220, 224, 231},
+ {224, 220, 245, 231},
+ {245, 220, 266, 231},
+ {269, 220, 290, 231},
+ {269, 189, 290, 205},
+ {279, 208, 290, 218}
+};
+
+static const BBPoint kPointsTbl1[] = {
+ {196, 191}, {202, 191}, {207, 191}, {212, 191}, {217, 191},
+ {223, 191}, {228, 191}, {233, 191}, {238, 191}, {244, 191},
+ {249, 191}
+};
+
+static const BBPoint kPointsTbl2[] = {
+ {196, 199}, {202, 199}, {207, 199}, {212, 199}, {217, 199},
+ {223, 199}, {228, 199}, {233, 199}, {238, 199}, {244, 199},
+ {249, 199}
+};
+
+static const struct { int frameIndex; byte flag; } kNoteFrameTbl[13] = {
+ {2, 0}, {2, 1}, {3, 0}, {3, 1}, {4, 0},
+ {5, 0}, {5, 1}, {6, 0}, {6, 1}, {0, 0},
+ {0, 1}, {1, 0}, {2, 0}
+};
+
+const int kTrackBarMinX = 172;
+const int kTrackBarMaxX = 272;
+
+bool MinigameBbAirGuitar::ptInRect(const Rect *r, int x, int y) {
+ return r && Common::Rect(r->left, r->top, r->right, r->bottom).contains(x, y);
+}
+
+bool MinigameBbAirGuitar::ptInPoly(const BBPolygon *poly, int x, int y) {
+ if (!poly)
+ return false;
+ const BBPoint *points = poly->points;
+ int pointsCount = poly->pointsCount;
+ bool result = false;
+ if (pointsCount > 0)
+ for (int i = 0, j = pointsCount - 1; i < pointsCount; j = i++)
+ if (((points[i].y > y) != (points[j].y > y)) &&
+ (x < (points[j].x - points[i].x) * (y - points[i].y) /
+ (points[j].y - points[i].y) + points[i].x))
+ result = !result;
+ return result;
+}
+
+void MinigameBbAirGuitar::buildDrawList(DrawList &drawList) {
+ switch (_gameState) {
+ case 0:
+ buildDrawList0(drawList);
+ break;
+ case 1:
+ buildDrawList1(drawList);
+ break;
+ }
+}
+
+void MinigameBbAirGuitar::buildDrawList0(DrawList &drawList) {
+
+ drawList.add(_objects[0].anim->frameIndices[0], _objects[0].x, _objects[0].y, 2000);
+
+ for (int i = 1; i < kMaxObjectsCount; ++i) {
+ Obj *obj = &_objects[i];
+ if (obj->kind)
+ drawList.add(obj->anim->frameIndices[obj->frameIndex], obj->x, obj->y, obj->y + 16);
+ }
+
+ if (_titleScreenSpriteIndex> 0)
+ drawList.add(_titleScreenSpriteIndex, 0, 0, 0);
+
+}
+
+void MinigameBbAirGuitar::buildDrawList1(DrawList &drawList) {
+
+ for (int i = 0; i < kMaxObjectsCount; ++i) {
+ Obj *obj = &_objects[i];
+ if (obj->kind)
+ drawList.add(obj->anim->frameIndices[obj->frameIndex], obj->x, obj->y, 255 - i);
+ }
+
+ if (_movingTrackBar) {
+ _trackBarX = _trackBarMouseX;
+ } else if (_totalTrackLength > 0) {
+ _trackBarX = 100 * _currTrackPos / _totalTrackLength + kTrackBarMinX;
+ } else {
+ _trackBarX = kTrackBarMinX;
+ }
+
+ if (_trackBarX > kTrackBarMaxX)
+ _trackBarX = kTrackBarMaxX;
+
+ _trackBarThumbRect.top = 208;
+ _trackBarThumbRect.bottom = 218;
+ _trackBarThumbRect.left = _trackBarX;
+ _trackBarThumbRect.right = _trackBarX + 6;
+
+ drawList.add(_objects[5].anim->frameIndices[0], _trackBarX, 208, 100);
+
+ if (_playerMode != 0) {
+ for (int i = 36; i < _vuMeterLeft2 + 36; ++i) {
+ int frameIndex = 0;
+ if (i >= 45)
+ frameIndex = 3;
+ else if (i >= 43)
+ frameIndex = 2;
+ else if (i >= 41)
+ frameIndex = 1;
+ drawList.add(_objects[i].anim->frameIndices[frameIndex], kPointsTbl1[i - 36].x, kPointsTbl1[i - 36].y, 254);
+ }
+ for (int i = 47; i < _vuMeterRight2 + 47; ++i) {
+ int frameIndex = 0;
+ if (i >= 56)
+ frameIndex = 3;
+ else if (i >= 54)
+ frameIndex = 2;
+ else if (i >= 52)
+ frameIndex = 1;
+ drawList.add(_objects[i].anim->frameIndices[frameIndex], kPointsTbl2[i - 47].x, kPointsTbl2[i - 47].y, 254);
+ }
+ }
+
+ if (_backgroundSpriteIndex > 0)
+ drawList.add(_backgroundSpriteIndex, 0, 0, 0);
+
+}
+
+void MinigameBbAirGuitar::drawSprites() {
+ DrawList drawList;
+ buildDrawList(drawList);
+ _vm->_screen->drawDrawList(drawList, _spriteModule);
+ _vm->_screen->copyToScreen();
+}
+
+void MinigameBbAirGuitar::initObjs() {
+ for (int i = 0; i < kMaxObjectsCount; ++i)
+ _objects[i].kind = 0;
+}
+
+MinigameBbAirGuitar::Obj *MinigameBbAirGuitar::getFreeObject() {
+ for (int i = 0; i < kMaxObjectsCount; ++i)
+ if (_objects[i].kind == 0)
+ return &_objects[i];
+ return 0;
+}
+
+void MinigameBbAirGuitar::initObjects() {
+ switch (_gameState) {
+ case 0:
+ initObjects0();
+ break;
+ case 1:
+ initObjects1();
+ break;
+ }
+}
+
+void MinigameBbAirGuitar::initObjects0() {
+ _objects[0].anim = getAnimation(0);
+ _objects[0].frameIndex = 0;
+ _objects[0].ticks = getAnimation(0)->frameTicks[0];
+ _objects[0].x = 160;
+ _objects[0].y = 120;
+ _objects[0].kind = 1;
+ _objects[1].anim = getAnimation(37);
+ _objects[1].frameIndex = 0;
+ _objects[1].ticks = getAnimation(37)->frameTicks[0];
+ _objects[1].x = 40;
+ _objects[1].y = 240;
+ _objects[1].kind = 2;
+ _objects[2].anim = getAnimation(36);
+ _objects[2].frameIndex = 0;
+ _objects[2].ticks = getAnimation(36)->frameTicks[0];
+ _objects[2].x = 280;
+ _objects[2].y = 240;
+ _objects[2].kind = 2;
+
+}
+
+void MinigameBbAirGuitar::initObjects1() {
+
+ for (int i = 0; i < 60; ++i)
+ _objects[i].kind = 0;
+
+ _objects[0].kind = 0;
+ _objects[0].kind = 1;
+ _objects[0].anim = getAnimation(0);
+ _objects[0].ticks = getAnimation(0)->frameTicks[0];
+ _objects[1].anim = getAnimation(1);
+ _objects[1].ticks = getAnimation(1)->frameTicks[0];
+ _objects[2].anim = getAnimation(2);
+ _objects[2].ticks = getAnimation(2)->frameTicks[0];
+ _objects[3].anim = getAnimation(3);
+ _objects[3].ticks = getAnimation(3)->frameTicks[0];
+ _objects[4].anim = getAnimation(4);
+ _objects[4].ticks = getAnimation(4)->frameTicks[0];
+ _objects[5].anim = getAnimation(5);
+ _objects[5].ticks = getAnimation(5)->frameTicks[0];
+ _objects[6].anim = getAnimation(6);
+ _objects[6].ticks = getAnimation(6)->frameTicks[0];
+ _objects[7].anim = getAnimation(8);
+ _objects[7].ticks = getAnimation(8)->frameTicks[0];
+ _objects[8].anim = getAnimation(9);
+ _objects[8].ticks = getAnimation(9)->frameTicks[0];
+ _objects[9].anim = getAnimation(10);
+ _objects[9].ticks = getAnimation(10)->frameTicks[0];
+ _objects[10].anim = getAnimation(11);
+ _objects[10].ticks = getAnimation(11)->frameTicks[0];
+ _objects[11].anim = getAnimation(12);
+ _objects[11].ticks = getAnimation(12)->frameTicks[0];
+ _objects[12].anim = getAnimation(13);
+ _objects[12].ticks = getAnimation(13)->frameTicks[0];
+ _objects[13].anim = getAnimation(14);
+ _objects[13].ticks = getAnimation(14)->frameTicks[0];
+ _objects[14].anim = getAnimation(15);
+ _objects[14].ticks = getAnimation(15)->frameTicks[0];
+ _objects[15].anim = getAnimation(16);
+ _objects[15].ticks = getAnimation(16)->frameTicks[0];
+ _objects[16].anim = getAnimation(17);
+ _objects[16].ticks = getAnimation(17)->frameTicks[0];
+ _objects[17].anim = getAnimation(18);
+ _objects[17].ticks = getAnimation(18)->frameTicks[0];
+ _objects[18].anim = getAnimation(19);
+ _objects[18].ticks = getAnimation(19)->frameTicks[0];
+ _objects[19].anim = getAnimation(20);
+ _objects[19].ticks = getAnimation(20)->frameTicks[0];
+ _objects[20].anim = getAnimation(21);
+ _objects[20].ticks = getAnimation(21)->frameTicks[0];
+ _objects[21].anim = getAnimation(11);
+ _objects[21].ticks = getAnimation(11)->frameTicks[0];
+ _objects[22].anim = getAnimation(22);
+ _objects[22].ticks = getAnimation(22)->frameTicks[0];
+ _objects[23].anim = getAnimation(23);
+ _objects[23].ticks = getAnimation(23)->frameTicks[0];
+ _objects[24].anim = getAnimation(24);
+ _objects[24].ticks = getAnimation(24)->frameTicks[0];
+ _objects[25].anim = getAnimation(25);
+ _objects[25].ticks = getAnimation(25)->frameTicks[0];
+ _objects[26].anim = getAnimation(26);
+ _objects[26].ticks = getAnimation(26)->frameTicks[0];
+ _objects[27].anim = getAnimation(27);
+ _objects[27].ticks = getAnimation(27)->frameTicks[0];
+ _objects[28].anim = getAnimation(28);
+ _objects[28].ticks = getAnimation(28)->frameTicks[0];
+ _objects[29].anim = getAnimation(29);
+ _objects[29].ticks = getAnimation(29)->frameTicks[0];
+ _objects[30].anim = getAnimation(30);
+ _objects[30].ticks = getAnimation(30)->frameTicks[0];
+ _objects[31].anim = getAnimation(31);
+ _objects[31].ticks = getAnimation(31)->frameTicks[0];
+ _objects[32].anim = getAnimation(32);
+ _objects[32].ticks = getAnimation(32)->frameTicks[0];
+ _objects[33].anim = getAnimation(33);
+ _objects[33].ticks = getAnimation(33)->frameTicks[0];
+ _objects[34].anim = getAnimation(34);
+ _objects[34].ticks = getAnimation(34)->frameTicks[0];
+ _objects[35].anim = getAnimation(35);
+ _objects[35].ticks = getAnimation(35)->frameTicks[0];
+
+ for (int i = 36; i <= 57; ++i) {
+ _objects[i].anim = getAnimation(7);
+ _objects[i].ticks = getAnimation(7)->frameTicks[0];
+ }
+
+ for (int i = 1; i <= 35; ++i) {
+ _objects[i].x = kObjPoints[i - 1].x;
+ _objects[i].y = kObjPoints[i - 1].y;
+ }
+
+ _objects[22].kind = 1;
+ _objects[6].kind = 1;
+ _objects[26].kind = 1;
+ _objects[26].frameIndex = 3;
+ _objects[27].kind = 1;
+ _objects[27].frameIndex = 3;
+ _objects[31].kind = 1;
+ _objects[31].frameIndex = 3;
+ _objects[32].kind = 1;
+ _objects[32].frameIndex = 3;
+ _objects[28].kind = 1;
+ _objects[33].kind = 1;
+ _objects[34].kind = 1;
+ _objects[35].kind = 1;
+
+ _track[0].noteNum = -1;
+ stop();
+ changePatch(0);
+
+}
+
+bool MinigameBbAirGuitar::updateStatus(int mouseX, int mouseY, uint mouseButtons) {
+ switch (_gameState) {
+ case 0:
+ return updateStatus0(mouseX, mouseY, mouseButtons);
+ case 1:
+ return updateStatus1(mouseX, mouseY, mouseButtons);
+ }
+ return false;
+}
+
+bool MinigameBbAirGuitar::updateStatus0(int mouseX, int mouseY, uint mouseButtons) {
+
+ if (mouseButtons & kAnyButtonDown) {
+ stopSound(1);
+ _rockTunePlaying = false;
+ _gameState = 1;
+ initObjects();
+ _gameTicks = 0;
+ } else {
+
+ if (!_rockTunePlaying) {
+ _rockTunePlaying = true;
+ playSound(1, true);
+ }
+
+ _objects[0].x = mouseX;
+ _objects[0].y = mouseY;
+
+ for (int i = 1; i < kMaxObjectsCount; ++i) {
+ Obj *obj = &_objects[i];
+ if (obj->kind && --obj->ticks == 0) {
+ ++obj->frameIndex;
+ if (obj->frameIndex >= obj->anim->frameCount)
+ obj->frameIndex = 0;
+ obj->ticks = obj->anim->frameTicks[obj->frameIndex];
+ }
+ }
+
+ }
+
+ return true;
+}
+
+bool MinigameBbAirGuitar::updateStatus1(int mouseX, int mouseY, uint mouseButtons) {
+
+ int currTicks = _vm->_system->getMillis();
+
+ if (_playerMode == 1 && _track[_trackIndex].ticks <= currTicks - _noteStartTime) {
+ noteOff(_track[_trackIndex].noteNum);
+ if (_trackIndex < _trackCount && _track[++_trackIndex].noteNum != -1)
+ noteOn(_track[_trackIndex].noteNum);
+ else
+ stop();
+ }
+
+ if (_vuMeterLeft1 - 2 <= _vuMeterLeft2) {
+ if (_vuMeterLeft1 + 1 >= _vuMeterLeft2) {
+ int incr = MIN(_vm->getRandom(4), 2) - 1;
+ if (incr < 0 && _vuMeterLeft2 == 0)
+ incr = -incr;
+ if (incr > 0 && _vuMeterLeft2 == 11)
+ incr = -incr;
+ _vuMeterLeft2 += incr;
+ } else {
+ --_vuMeterLeft2;
+ }
+ } else {
+ ++_vuMeterLeft2;
+ }
+
+ if (_vuMeterRight1 - 2 <= _vuMeterRight2) {
+ if (_vuMeterRight1 + 1 >= _vuMeterRight2) {
+ int incr = MIN(_vm->getRandom(4), 2) - 1;
+ if (incr < 0 && _vuMeterRight2 == 0)
+ incr = -incr;
+ if (incr > 0 && _vuMeterRight2 == 11)
+ incr = -incr;
+ _vuMeterRight2 += incr;
+ } else {
+ --_vuMeterRight2;
+ }
+ } else {
+ ++_vuMeterRight2;
+ }
+
+ if (_resetAnims && _vm->_system->getMillis() - _noteStartTime >= 1000)
+ resetObjs();
+
+ _objects[0].x = mouseX;
+ _objects[0].y = mouseY;
+
+ _trackBarMouseX = CLIP(mouseX, kTrackBarMinX, kTrackBarMaxX);
+
+ bool checkClick = false;
+
+ if (mouseButtons & kAnyButtonClicked) {
+ checkClick = true;
+ } else if (!(mouseButtons & kAnyButtonDown)) {
+ afterButtonReleased();
+ } else if (!_movingTrackBar && ((_currButtonNum >= 14 && ptInPoly(_currPianoKeyArea, mouseX, mouseY)) || ptInRect(_currPlayerButtonRect, mouseX, mouseY))) {
+ if (_currButtonNum == 5 && _trackIndex > 0) {
+ --_trackIndex;
+ calcTotalTicks2();
+ } else if (_currButtonNum == 13 && _trackIndex < _trackCount) {
+ ++_trackIndex;
+ calcTotalTicks2();
+ }
+ } else if (!_movingTrackBar)
+ checkClick = true;
+
+ if (checkClick) {
+
+ afterButtonReleased();
+ _objects[0].frameIndex = 1;
+
+ if (ptInRect(&kRect2, mouseX, mouseY)) {
+
+ if (_playerMode != 1 && ptInRect(&kPianoRect, mouseX, mouseY)) {
+ for (int i = 0; i <= 12; ++i) {
+ if (ptInPoly(&kPianoKeyAreas[i], mouseX, mouseY)) {
+ _currButtonNum = i + 14;
+ _currPianoKeyArea = &kPianoKeyAreas[i];
+ _objects[11].kind = 1;
+ _objects[11].x = kPianoKeyInfos[i].x;
+ _objects[11].y = kPianoKeyInfos[i].y;
+ _objects[11].frameIndex = kPianoKeyInfos[i].frameIndex;
+ noteOn(i);
+ break;
+ }
+ }
+ } else if (_playerMode != 1 && ptInRect(&_trackBarThumbRect, mouseX, mouseY)) {
+ _movingTrackBar = true;
+ } else {
+
+ int playerButtonNum = -1;
+ for (int i = 0; i < 14; ++i) {
+ if (ptInRect(&kPlayerButtonRects[i], mouseX, mouseY)) {
+ playerButtonNum = i;
+ break;
+ }
+ }
+
+ if (playerButtonNum >= 0) {
+ _currButtonNum = playerButtonNum;
+ _currPlayerButtonRect = &kPlayerButtonRects[playerButtonNum];
+
+ switch (playerButtonNum) {
+
+ case 0:
+ if (_playerMode == 0) {
+ changePatch(0);
+ _currFrameIndex = &_objects[18 + 0].frameIndex;
+ *_currFrameIndex = 0;
+ }
+ break;
+
+ case 1:
+ if (_playerMode == 0) {
+ changePatch(1);
+ _currFrameIndex = &_objects[18 + 1].frameIndex;
+ *_currFrameIndex = 0;
+ }
+ break;
+
+ case 2:
+ if (_playerMode == 0) {
+ changePatch(2);
+ _currFrameIndex = &_objects[18 + 2].frameIndex;
+ *_currFrameIndex = 0;
+ }
+ break;
+
+ case 3:
+ _btn3KindToggle = !_btn3KindToggle;
+ _objects[9].kind = _btn3KindToggle ? 0 : 1;
+ _objects[22].frameIndex = _btn3KindToggle ? 0 : 1;
+ break;
+
+ case 4:
+ if (_playerMode == 0) {
+ _objects[1].kind = 1;
+ _currFrameIndex = &_objects[1].frameIndex;
+ _objects[1].frameIndex = 0;
+ }
+ break;
+
+ case 5:
+ if (_playerMode == 0) {
+ if (_trackIndex > 0)
+ --_trackIndex;
+ _objects[3].kind = 1;
+ calcTotalTicks2();
+ }
+ break;
+
+ case 6:
+ stop();
+ _currFrameIndex = &_objects[15].frameIndex;
+ _objects[15].frameIndex = 0;
+ break;
+
+ case 7:
+ if (_playerMode == 0) {
+ play();
+ _currFrameIndex = &_objects[12].frameIndex;
+ _objects[12].frameIndex = 0;
+ }
+ break;
+
+ case 8:
+ if (_playerMode == 0) {
+ _trackIndex = 0;
+ _objects[16].kind = 1;
+ calcTotalTicks2();
+ }
+ break;
+
+ case 9:
+ if (_playerMode == 0) {
+ _trackIndex = _trackCount;
+ _objects[17].kind = 1;
+ calcTotalTicks2();
+ }
+ break;
+
+ case 10:
+ if (_playerMode == 0) {
+ record();
+ _currFrameIndex = &_objects[13].frameIndex;
+ _objects[13].frameIndex = 0;
+ }
+ break;
+
+ case 11:
+ if (_playerMode == 0) {
+ setPlayerMode3();
+ _currFrameIndex = &_objects[14].frameIndex;
+ _objects[14].frameIndex = 0;
+ }
+ break;
+
+ case 12:
+ if (_playerMode == 0) {
+ _objects[2].kind = 1;
+ _currFrameIndex = &_objects[2].frameIndex;
+ _objects[2].frameIndex = 0;
+ }
+ break;
+
+ case 13:
+ if (_playerMode == 0) {
+ if (_trackIndex < _trackCount)
+ ++_trackIndex;
+ _objects[4].kind = 1;
+ calcTotalTicks2();
+ }
+ break;
+
+ }
+ }
+ }
+ }
+ }
+
+ if (_playerMode != 0) {
+ _currTrackPos = currTicks + _actionStartTrackPos - _actionStartTime;
+ if (_currTrackPos > _actionTrackPos && _playerMode != 1) {
+ if (_currTrackPos >= 15000) {
+ _currTrackPos = 15000;
+ _actionTrackPos = 15000;
+ stop();
+ } else {
+ _actionTrackPos = currTicks + _actionStartTrackPos - _actionStartTime;
+ }
+ }
+ }
+
+ if (_buttonClickTicks + 1000 < currTicks)
+ _buttonClickTicks = currTicks;
+
+ int newKind = _buttonClickTicks + 500 < currTicks ? 1 : 0;
+
+ switch (_playerMode) {
+
+ case 1:
+ if (_currButtonNum == 7) {
+ _objects[12].kind = 1;
+ _objects[12].frameIndex = 0;
+ } else {
+ _objects[12].kind = newKind;
+ _objects[12].frameIndex = 1;
+ }
+ break;
+
+ case 2:
+ if (_currButtonNum == 10) {
+ _objects[13].kind = 1;
+ _objects[13].frameIndex = 0;
+ } else {
+ _objects[13].kind = newKind;
+ _objects[13].frameIndex = 1;
+ }
+ break;
+
+ case 3:
+ if (_currButtonNum == 11) {
+ _objects[14].kind = 1;
+ _objects[14].frameIndex = 0;
+ } else {
+ _objects[14].kind = newKind;
+ _objects[14].frameIndex = 1;
+ }
+ break;
+
+ }
+
+ updateObjs();
+
+ return true;
+}
+
+void MinigameBbAirGuitar::updateObjs() {
+ for (int i = 24; i <= 33; ++i) {
+ Obj *obj = &_objects[i];
+ if (obj->kind && --obj->ticks == 0) {
+ if (obj->frameIndex + 1 >= obj->anim->frameCount) {
+ obj->ticks = -1;
+ } else {
+ ++obj->frameIndex;
+ obj->ticks = obj->anim->frameTicks[obj->frameIndex];
+ }
+ }
+ }
+}
+
+int MinigameBbAirGuitar::run(bool fromMainGame) {
+
+ memset(_objects, 0, sizeof(_objects));
+
+ _modified = false;
+ _currPatchNum = -1;
+ _btn3KindToggle = 0;
+ _currButtonNum = 27;
+ _actionStartTime = 0;
+ _currFrameIndex = 0;
+ _currPlayerButtonRect = 0;
+ _currPianoKeyArea = 0;
+ _trackCount = 0;
+ _trackIndex = 0;
+ _totalTrackLength = 0;
+ _actionTrackPos = 0;
+ _noteStartTime = 0;
+ _actionStartTrackPos = 0;
+ _trackBarX = kTrackBarMinX;
+ _currTrackPos = 0;
+ _currNoteNum = -2;
+ _resetAnims = false;
+ _vuMeterLeft2 = 0;
+ _vuMeterRight2 = 0;
+ _vuMeterLeft1 = 0;
+ _vuMeterRight1 = 0;
+ _rockTunePlaying = false;
+
+ _backgroundSpriteIndex = 97;
+ _titleScreenSpriteIndex = 98;
+
+ _fromMainGame = fromMainGame;
+
+ _gameState = 0;
+ _gameTicks = 0;
+ _gameResult = 0;
+ _gameDone = false;
+ initObjects();
+
+ _spriteModule = new SpriteModule();
+ _spriteModule->load("bbairg/bbairg.000");
+
+ Palette palette = _spriteModule->getPalette();
+ _vm->_screen->setPalette(palette);
+
+ loadSounds();
+
+ while (!_vm->shouldQuit() &&!_gameDone) {
+ _vm->updateEvents();
+ update();
+ }
+
+ _vm->_sound->unloadSounds();
+
+ delete _spriteModule;
+
+ return _gameResult;
+}
+
+void MinigameBbAirGuitar::update() {
+
+ int currTicks, inputTicks;
+
+ if (_gameTicks > 0) {
+ currTicks = _vm->_system->getMillis();
+ inputTicks = 3 * (currTicks - _gameTicks) / 50;
+ _gameTicks = currTicks - (currTicks - _gameTicks - 50 * inputTicks / 3);
+ } else {
+ inputTicks = 1;
+ _gameTicks = _vm->_system->getMillis();
+ }
+
+ if (_vm->_keyCode == Common::KEYCODE_ESCAPE) {
+ _gameDone = true;
+ return;
+ }
+
+ if (inputTicks == 0)
+ return;
+
+ bool done;
+
+ do {
+ done = !updateStatus(_vm->_mouseX, _vm->_mouseY, _vm->_mouseButtons);
+ _vm->_mouseButtons &= ~kLeftButtonClicked;
+ _vm->_mouseButtons &= ~kRightButtonClicked;
+ _vm->_keyCode = Common::KEYCODE_INVALID;
+ } while (--inputTicks && _gameTicks > 0 && !done);
+
+ drawSprites();
+
+ _vm->_system->delayMillis(10);
+
+}
+
+void MinigameBbAirGuitar::play() {
+ if (_track[_trackIndex].noteNum != -1) {
+ _playerMode = 1;
+ _objects[7].kind = 1;
+ _objects[8].kind = 0;
+ _objects[15].kind = 0;
+ _actionStartTime = _vm->_system->getMillis();
+ _actionStartTrackPos = _currTrackPos;
+ noteOn(_track[_trackIndex].noteNum);
+ }
+}
+
+
+void MinigameBbAirGuitar::record() {
+ _playerMode = 2;
+ _objects[7].kind = 1;
+ _objects[8].kind = 0;
+ _objects[15].kind = 0;
+ _totalTrackLength = 15000;
+ _actionStartTime = _vm->_system->getMillis();
+ _actionStartTrackPos = _currTrackPos;
+ _noteStartTime = _vm->_system->getMillis();
+ _actionTrackPos = _currTrackPos;
+ _trackCount = _trackIndex;
+ _vuMeterRight1 = 0;
+ _vuMeterRight2 = 0;
+ _vuMeterLeft1 = 0;
+ _vuMeterLeft2 = 0;
+ _modified = true;
+ _track[_trackIndex].noteNum = -2;
+}
+
+void MinigameBbAirGuitar::setPlayerMode3() {
+ _playerMode = 3;
+ _objects[7].kind = 1;
+ _objects[8].kind = 0;
+ _objects[15].kind = 0;
+ _totalTrackLength = 15000;
+ _actionStartTime = _vm->_system->getMillis();
+ _actionStartTrackPos = _currTrackPos;
+ _noteStartTime = _vm->_system->getMillis();
+ _actionTrackPos = _currTrackPos;
+ _trackCount = _trackIndex;
+ _vuMeterRight1 = 0;
+ _vuMeterRight2 = 0;
+ _vuMeterLeft1 = 0;
+ _vuMeterLeft2 = 0;
+ _modified = true;
+ _track[_trackIndex].noteNum = -2;
+}
+
+void MinigameBbAirGuitar::stop() {
+ noteOff(_currNoteNum);
+ if (_playerMode == 2 || _playerMode == 3) {
+ _totalTrackLength = _actionTrackPos;
+ _track[_trackCount].noteNum = -1;
+ }
+ _playerMode = 0;
+ _objects[7].kind = 0;
+ _objects[8].kind = 1;
+ _objects[15].kind = 1;
+ _objects[15].frameIndex = 1;
+ _objects[12].kind = 0;
+ _objects[13].kind = 0;
+ _objects[14].kind = 0;
+ resetObjs();
+}
+
+void MinigameBbAirGuitar::changePatch(int patchNum) {
+
+ resetObjs();
+
+ if (patchNum == -1 || patchNum != _currPatchNum)
+ _currPatchNum = -1;
+
+ _objects[20].kind = 0;
+ _objects[19].kind = _objects[20].kind;
+ _objects[18].kind = _objects[19].kind;
+ _objects[patchNum + 18].kind = 1;
+ _objects[patchNum + 18].frameIndex = 1;
+ _objects[6].frameIndex = patchNum;
+ _currPatchNum = patchNum;
+}
+
+void MinigameBbAirGuitar::afterButtonReleased() {
+ if (_movingTrackBar) {
+ _movingTrackBar = false;
+ _currTrackPos = _totalTrackLength * (_trackBarX - kTrackBarMinX) / 100;
+ calcTotalTicks1();
+ } else {
+ switch (_currButtonNum) {
+ case 0:
+ case 1:
+ case 2:
+ *_currFrameIndex = 1;
+ break;
+ case 4:
+ *_currFrameIndex = 1;
+ // TODO Run load dialog
+ break;
+ case 5:
+ _objects[3].kind = 0;
+ break;
+ case 6:
+ *_currFrameIndex = 1;
+ break;
+ case 7:
+ *_currFrameIndex = 1;
+ break;
+ case 8:
+ _objects[16].kind = 0;
+ break;
+ case 9:
+ _objects[17].kind = 0;
+ break;
+ case 10:
+ *_currFrameIndex = 1;
+ break;
+ case 11:
+ *_currFrameIndex = 1;
+ break;
+ case 12:
+ *_currFrameIndex = 1;
+ // TODO Run save dialog
+ break;
+ case 13:
+ _objects[4].kind = 0;
+ break;
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ noteOff(_currButtonNum - 14);
+ break;
+ }
+ }
+
+ _objects->frameIndex = 0;
+ _currPlayerButtonRect = 0;
+ _currPianoKeyArea = 0;
+ _currButtonNum = 27;
+}
+
+void MinigameBbAirGuitar::calcTotalTicks2() {
+ _currTrackPos = 0;
+ for (int i = 0; i < _trackIndex; ++i)
+ _currTrackPos += _track[i].ticks;
+}
+
+void MinigameBbAirGuitar::calcTotalTicks1() {
+ int totalTicks = 0;
+ // TODO Try to clean this up
+ _trackIndex = 0;
+ if (_track[0].ticks <= _currTrackPos) {
+ do {
+ totalTicks += _track[_trackIndex].ticks;
+ if (_trackIndex >= _trackCount)
+ break;
+ ++_trackIndex;
+ } while (totalTicks + _track[_trackIndex].ticks <= _currTrackPos);
+ }
+ _currTrackPos = totalTicks;
+}
+
+void MinigameBbAirGuitar::noteOn(int noteNum) {
+
+ if (_currNoteNum != -2) {
+ if (noteNum == _currNoteNum)
+ return;
+ noteOff(_currNoteNum);
+ }
+
+ if (noteNum == -2) {
+ _vuMeterRight1 = 0;
+ _vuMeterRight2 = 0;
+ _vuMeterLeft1 = 0;
+ _vuMeterLeft2 = 0;
+ } else {
+ playNote(noteNum);
+ _vuMeterRight1 = 10;
+ _vuMeterRight2 = 10;
+ _vuMeterLeft1 = 10;
+ _vuMeterLeft2 = 10;
+ if (_btn3KindToggle) {
+ _objects[23].kind = 1;
+ _objects[23].frameIndex = noteNum;
+ } else {
+ _objects[10].kind = 1;
+ _objects[10].frameIndex = kNoteFrameTbl[noteNum].frameIndex;
+ if (kNoteFrameTbl[noteNum].flag) {
+ _objects[21].kind = 1;
+ _objects[21].frameIndex = 7;
+ }
+ }
+ }
+
+ _currNoteNum = noteNum;
+
+ if (_playerMode == 2 || _playerMode == 3) {
+ _ticksDelta = _vm->_system->getMillis() - _noteStartTime;
+ _track[_trackCount].ticks = _ticksDelta;
+ if (_trackCount < kMaxTracks)
+ ++_trackCount;
+ _track[_trackCount].noteNum = noteNum;
+ }
+
+ _noteStartTime = _vm->_system->getMillis();
+
+ if (noteNum != -2) {
+ _resetAnims = false;
+ if (_currPatchNum == 0) {
+ _objects[25].kind = 1;
+ _objects[28].kind = 0;
+ _objects[25].frameIndex = 0;
+ _objects[25].ticks = getAnimation(25)->frameTicks[0];
+ _objects[26].frameIndex = 0;
+ _objects[26].ticks = getAnimation(26)->frameTicks[0];
+ _objects[27].frameIndex = 0;
+ _objects[27].ticks = getAnimation(27)->frameTicks[0];
+ _objects[30].kind = 1;
+ _objects[33].kind = 0;
+ _objects[30].frameIndex = 0;
+ _objects[30].ticks = getAnimation(30)->frameTicks[0];
+ _objects[31].frameIndex = 0;
+ _objects[31].ticks = getAnimation(31)->frameTicks[0];
+ _objects[32].frameIndex = 0;
+ _objects[32].ticks = getAnimation(32)->frameTicks[0];
+ } else if (_currPatchNum == 1) {
+ _objects[29].kind = 1;
+ _objects[33].kind = 0;
+ _objects[29].frameIndex = 0;
+ _objects[29].ticks = getAnimation(29)->frameTicks[0];
+ _objects[31].frameIndex = 0;
+ _objects[31].ticks = getAnimation(31)->frameTicks[0];
+ _objects[32].frameIndex = 0;
+ _objects[32].ticks = getAnimation(32)->frameTicks[0];
+ } else if (_currPatchNum == 2) {
+ _objects[24].kind = 1;
+ _objects[28].kind = 0;
+ _objects[24].frameIndex = 0;
+ _objects[24].ticks = getAnimation(24)->frameTicks[0];
+ _objects[26].frameIndex = 0;
+ _objects[26].ticks = getAnimation(26)->frameTicks[0];
+ _objects[27].frameIndex = 0;
+ _objects[27].ticks = getAnimation(27)->frameTicks[0];
+ }
+ }
+
+}
+
+void MinigameBbAirGuitar::noteOff(int noteNum) {
+
+ if (_currNoteNum != noteNum)
+ return;
+
+ if (noteNum != -2)
+ stopNote(noteNum);
+
+ _objects[21].kind = 0;
+ _objects[23].kind = _objects[21].kind;
+ _objects[10].kind = _objects[23].kind;
+
+ _vuMeterRight1 = 0;
+ _vuMeterRight2 = 0;
+ _vuMeterLeft1 = 0;
+ _vuMeterLeft2 = 0;
+
+ _currNoteNum = -2;
+
+ _objects[11].kind = 0;
+
+ _ticksDelta = _vm->_system->getMillis() - _noteStartTime;
+
+ if (_playerMode == 2 || _playerMode == 3) {
+ if (_actionTrackPos + _ticksDelta > 15000)
+ _ticksDelta = 15000 - _actionTrackPos;
+ _track[_trackCount].ticks = _ticksDelta;
+ if (_trackCount < 2048)
+ ++_trackCount;
+ _track[_trackCount].noteNum = -2;
+ _noteStartTime = _vm->_system->getMillis();
+ }
+
+ if (noteNum != -2) {
+ if (_playerMode == 0) {
+ _resetAnims = true;
+ _noteStartTime = _vm->_system->getMillis();
+ }
+ if (_currPatchNum == 0) {
+ _objects[25].frameIndex = 3;
+ _objects[25].ticks = -1;
+ _objects[26].frameIndex = 3;
+ _objects[26].ticks = -1;
+ _objects[27].frameIndex = 3;
+ _objects[27].ticks = -1;
+ _objects[30].frameIndex = 3;
+ _objects[30].ticks = -1;
+ _objects[31].frameIndex = 3;
+ _objects[31].ticks = -1;
+ _objects[32].frameIndex = 3;
+ _objects[32].ticks = -1;
+ } else if (_currPatchNum == 1) {
+ _objects[29].frameIndex = 3;
+ _objects[29].ticks = -1;
+ _objects[31].frameIndex = 3;
+ _objects[31].ticks = -1;
+ _objects[32].frameIndex = 3;
+ _objects[32].ticks = -1;
+ } else if (_currPatchNum == 2) {
+ _objects[24].frameIndex = 2;
+ _objects[24].ticks = -1;
+ _objects[26].frameIndex = 3;
+ _objects[26].ticks = -1;
+ _objects[27].frameIndex = 3;
+ _objects[27].ticks = -1;
+ }
+ }
+
+}
+
+void MinigameBbAirGuitar::resetObjs() {
+ _resetAnims = false;
+ _objects[25].kind = 0;
+ _objects[24].kind = 0;
+ _objects[28].kind = 1;
+ _objects[26].frameIndex = 0;
+ _objects[26].ticks = -1;
+ _objects[27].frameIndex = 0;
+ _objects[27].ticks = -1;
+ _objects[30].kind = 0;
+ _objects[29].kind = 0;
+ _objects[33].kind = 1;
+ _objects[31].frameIndex = 0;
+ _objects[31].ticks = -1;
+ _objects[32].frameIndex = 0;
+ _objects[32].ticks = -1;
+}
+
+void MinigameBbAirGuitar::loadSounds() {
+ _vm->_sound->loadSound("bbairg/audio/rocktune.aif");
+ for (uint i = 0; i < kPatchDirectoriesCount; ++i) {
+ const char *patchDirectory = kPatchDirectories[i];
+ for (uint j = 0; j < kNoteSoundFilenamesCount; ++j) {
+ Common::String filename = Common::String::format("bbairg/audio/%s/%s", patchDirectory, kNoteSoundFilenames[j]);
+ _vm->_sound->loadSound(filename.c_str());
+ }
+ }
+}
+
+void MinigameBbAirGuitar::playNote(int noteNum) {
+ if (noteNum >= 0 && _currPatchNum >= 0)
+ playSound(2 + _currPatchNum * kNoteSoundFilenamesCount + noteNum);
+}
+
+void MinigameBbAirGuitar::stopNote(int noteNum) {
+ if (noteNum >= 0 && _currPatchNum >= 0)
+ stopSound(2 + _currPatchNum * kNoteSoundFilenamesCount + noteNum);
+}
+
+} // End of namespace Bbvs