aboutsummaryrefslogtreecommitdiff
path: root/sky
diff options
context:
space:
mode:
authorRobert Göffringmann2003-06-22 21:42:59 +0000
committerRobert Göffringmann2003-06-22 21:42:59 +0000
commitf891aceee307fa614fcd312b6f567792f1b95ae1 (patch)
tree90d90d5dfff3ce150c793cd534ddab6e63b012e2 /sky
parent8595f30740beb3ed9d975f895578b19e18d2c223 (diff)
downloadscummvm-rg350-f891aceee307fa614fcd312b6f567792f1b95ae1.tar.gz
scummvm-rg350-f891aceee307fa614fcd312b6f567792f1b95ae1.tar.bz2
scummvm-rg350-f891aceee307fa614fcd312b6f567792f1b95ae1.zip
native mt32 support and basic control panel (incomplete)
doesn't work with all versions, probably file numbers were changed svn-id: r8632
Diffstat (limited to 'sky')
-rw-r--r--sky/control.cpp660
-rw-r--r--sky/control.h194
-rw-r--r--sky/logic.cpp1
-rw-r--r--sky/module.mk2
-rw-r--r--sky/music/adlibmusic.cpp6
-rw-r--r--sky/music/adlibmusic.h1
-rw-r--r--sky/music/gmmusic.cpp10
-rw-r--r--sky/music/gmmusic.h1
-rw-r--r--sky/music/mt32music.cpp103
-rw-r--r--sky/music/mt32music.h1
-rw-r--r--sky/music/musicbase.cpp2
-rw-r--r--sky/music/musicbase.h2
-rw-r--r--sky/sky.cpp15
-rw-r--r--sky/sky.h4
-rw-r--r--sky/sound.cpp2
15 files changed, 934 insertions, 70 deletions
diff --git a/sky/control.cpp b/sky/control.cpp
new file mode 100644
index 0000000000..491cd2d4da
--- /dev/null
+++ b/sky/control.cpp
@@ -0,0 +1,660 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "sky/control.h"
+#include "sky/skydefs.h"
+#include "sky/sky.h"
+#include "common/file.h"
+
+SkyConResource::SkyConResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen) {
+
+ _spriteData = (dataFileHeader*)pSpData;
+ _numSprites = pNSprites;
+ _curSprite = pCurSprite;
+ _x = pX;
+ _y = pY;
+ _text = pText;
+ _onClick = pOnClick;
+ _system = system;
+ _screen = screen;
+}
+
+bool SkyConResource::isMouseOver(uint32 mouseX, uint32 mouseY) {
+
+ if ((mouseX >= _x) && (mouseY >= _y) && ((uint16)mouseX <= _x + _spriteData->s_width) && ((uint16)mouseY <= _y + _spriteData->s_height))
+ return true;
+ else
+ return false;
+}
+
+void SkyConResource::drawToScreen(bool doMask) {
+
+ uint8 *screenPos = _y * GAME_SCREEN_WIDTH + _x + _screen;
+ uint8 *updatePos = screenPos;
+
+ if (!_spriteData) return;
+ uint8 *spriteData = ((uint8*)_spriteData) + sizeof(dataFileHeader);
+ spriteData += _spriteData->s_sp_size * _curSprite;
+ if (doMask) {
+ for (uint16 cnty = 0; cnty < _spriteData->s_height; cnty++) {
+ for (uint16 cntx = 0; cntx < _spriteData->s_width; cntx++) {
+ if (spriteData[cntx]) screenPos[cntx] = spriteData[cntx];
+ }
+ screenPos += GAME_SCREEN_WIDTH;
+ spriteData += _spriteData->s_width;
+ }
+ } else {
+ for (uint16 cnty = 0; cnty < _spriteData->s_height; cnty++) {
+ memcpy(screenPos, spriteData, _spriteData->s_width);
+ screenPos += GAME_SCREEN_WIDTH;
+ spriteData += _spriteData->s_width;
+ }
+ }
+ _system->copy_rect(updatePos, GAME_SCREEN_WIDTH, _x, _y, _spriteData->s_width, _spriteData->s_height);
+}
+
+SkyTextResource::SkyTextResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen) :
+ SkyConResource(pSpData, pNSprites, pCurSprite, pX, pY, pText, pOnClick, system, screen) {
+ _oldScreen = (uint8*)malloc(PAN_CHAR_HEIGHT * PAN_LINE_WIDTH);
+ _oldY = 0;
+ _oldX = GAME_SCREEN_WIDTH;
+}
+
+SkyTextResource::~SkyTextResource(void) {
+ free(_oldScreen);
+}
+
+void SkyTextResource::drawToScreen(bool doMask) {
+
+ doMask = true;
+ uint16 cnty, cntx, cpWidth;
+ if ((_oldX == _x) && (_oldY == _y) && (_spriteData)) return;
+ if (_oldX < GAME_SCREEN_WIDTH) {
+ cpWidth = (PAN_LINE_WIDTH > (GAME_SCREEN_WIDTH - _oldX))?(GAME_SCREEN_WIDTH - _oldX):(PAN_LINE_WIDTH);
+ for (cnty = 0; cnty < PAN_CHAR_HEIGHT; cnty++)
+ memcpy(_screen + (cnty + _oldY) * GAME_SCREEN_WIDTH + _oldX, _oldScreen + cnty * PAN_LINE_WIDTH, cpWidth);
+ _system->copy_rect(_screen + _oldY * GAME_SCREEN_WIDTH + _oldX, GAME_SCREEN_WIDTH, _oldX, _oldY, cpWidth, PAN_CHAR_HEIGHT);
+ }
+ if (!_spriteData) {
+ _oldX = GAME_SCREEN_WIDTH;
+ return;
+ }
+ _oldX = _x;
+ _oldY = _y;
+ cpWidth = (PAN_LINE_WIDTH > (GAME_SCREEN_WIDTH - _x))?(GAME_SCREEN_WIDTH - _x):(PAN_LINE_WIDTH);
+ uint8 *screenPos = _screen + _y * GAME_SCREEN_WIDTH + _x;
+ uint8 *copyDest = _oldScreen;
+ uint8 *copySrc = ((uint8*)_spriteData) + sizeof(dataFileHeader);
+ for (cnty = 0; cnty < PAN_CHAR_HEIGHT; cnty++) {
+ memcpy(copyDest, screenPos, cpWidth);
+ for (cntx = 0; cntx < PAN_LINE_WIDTH; cntx++)
+ if (copySrc[cntx]) screenPos[cntx] = copySrc[cntx];
+ copySrc += _spriteData->s_width;
+ copyDest += PAN_LINE_WIDTH;
+ screenPos += GAME_SCREEN_WIDTH;
+ }
+ _system->copy_rect(_screen + _y * GAME_SCREEN_WIDTH + _x, GAME_SCREEN_WIDTH, _x, _y, cpWidth, PAN_CHAR_HEIGHT);
+}
+
+SkyControl::SkyControl(SkyScreen *screen, SkyDisk *disk, SkyMouse *mouse, SkyText *text, SkyMusicBase *music, OSystem *system, const char *savePath) {
+
+ _skyScreen = screen;
+ _skyDisk = disk;
+ _skyMouse = mouse;
+ _skyText = text;
+ _skyMusic = music;
+ _system = system;
+ _savePath = savePath;
+}
+
+SkyConResource *SkyControl::createResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, int16 pX, int16 pY, uint32 pText, uint8 pOnClick, uint8 panelType) {
+
+ if (pText) pText += 0x7000;
+ if (panelType == MAINPANEL) {
+ pX += MPNL_X;
+ pY += MPNL_Y;
+ } else {
+ pX += SPNL_X;
+ pY += SPNL_Y;
+ }
+ return new SkyConResource(pSpData, pNSprites, pCurSprite, pX, pY, pText, pOnClick, _system, _screenBuf);
+}
+
+void SkyControl::removePanel(void) {
+
+ free(_screenBuf);
+ free(_sprites.controlPanel); free(_sprites.button);
+ free(_sprites.buttonDown); free(_sprites.savePanel);
+ free(_sprites.yesNo); free(_sprites.slide);
+ free(_sprites.slide2); free(_sprites.slode);
+ free(_sprites.slode2); free(_sprites.musicBodge);
+ delete _controlPanel; delete _exitButton;
+ delete _slide; delete _slide2;
+ delete _slode; delete _restorePanButton;
+ delete _savePanButton; delete _dosPanButton;
+ delete _restartPanButton; delete _fxPanButton;
+ delete _musicPanButton; delete _bodge;
+ delete _yesNo; delete _text;
+}
+
+void SkyControl::initPanel(void) {
+
+ _screenBuf = (uint8*)malloc(GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
+ memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
+
+ uint16 volY = (127 - _skyMusic->giveVolume()) / 4 + 59 - MPNL_Y; // volume slider's Y coordinate
+
+ _sprites.controlPanel = _skyDisk->loadFile(60500, NULL);
+ _sprites.button = _skyDisk->loadFile(60501, NULL);
+ _sprites.buttonDown = _skyDisk->loadFile(60502, NULL);
+ _sprites.savePanel = _skyDisk->loadFile(60503, NULL);
+ _sprites.yesNo = _skyDisk->loadFile(60504, NULL);
+ _sprites.slide = _skyDisk->loadFile(60505, NULL);
+ _sprites.slode = _skyDisk->loadFile(60506, NULL);
+ _sprites.slode2 = _skyDisk->loadFile(60507, NULL);
+ _sprites.slide2 = _skyDisk->loadFile(60508, NULL);
+ _sprites.musicBodge = _skyDisk->loadFile(60509, NULL);
+
+ //Main control panel: X Y Text OnClick
+ _controlPanel = createResource(_sprites.controlPanel, 1, 0, 0, 0, 0, DO_NOTHING, MAINPANEL);
+ _exitButton = createResource( _sprites.button, 3, 0, 16, 125, 50, EXIT, MAINPANEL);
+ _slide = createResource( _sprites.slide2, 1, 0, 19, 99, 95, SPEED_SLIDE, MAINPANEL);
+ _slide2 = createResource( _sprites.slide2, 1, 0, 19,volY, 14, MUSIC_SLIDE, MAINPANEL);
+ _slode = createResource( _sprites.slode2, 1, 0, 9, 49, 0, DO_NOTHING, MAINPANEL);
+ _restorePanButton = createResource( _sprites.button, 3, 0, 58, 19, 51, REST_GAME_PANEL, MAINPANEL);
+ _savePanButton = createResource( _sprites.button, 3, 0, 58, 39, 48, SAVE_GAME_PANEL, MAINPANEL);
+ _dosPanButton = createResource( _sprites.button, 3, 0, 58, 59, 93, QUIT_TO_DOS, MAINPANEL);
+ _restartPanButton = createResource( _sprites.button, 3, 0, 58, 79, 94, RESTART, MAINPANEL);
+ if (SkyState::_systemVars.systemFlags & SF_FX_OFF)
+ _fxPanButton = createResource( _sprites.button, 3, 0, 58, 99, 86, TOGGLE_FX, MAINPANEL);
+ else
+ _fxPanButton = createResource( _sprites.button, 3, 2, 58, 99, 87, TOGGLE_FX, MAINPANEL);
+ _musicPanButton = createResource( _sprites.button, 3, 0, 58, 119, 35, TOGGLE_MS, MAINPANEL);
+ _bodge = createResource( _sprites.musicBodge, 2, 1, 98, 115, 0, DO_NOTHING, MAINPANEL);
+ _yesNo = createResource( _sprites.yesNo, 1, 0, -2, 40, 0, DO_NOTHING, MAINPANEL);
+
+ _text = new SkyTextResource(NULL, 1, 0, 15, 137, 0, DO_NOTHING, _system, _screenBuf);
+ _controlPanLookList[0] = _exitButton;
+ _controlPanLookList[1] = _restorePanButton;
+ _controlPanLookList[2] = _savePanButton;
+ _controlPanLookList[3] = _dosPanButton;
+ _controlPanLookList[4] = _restartPanButton;
+ _controlPanLookList[5] = _fxPanButton;
+ _controlPanLookList[6] = _musicPanButton;
+ _controlPanLookList[7] = _slide;
+ _controlPanLookList[8] = _slide2;
+
+ // save/restore panel
+ _savePanel = createResource( _sprites.savePanel, 1, 0, 0, 0, 0, DO_NOTHING, SAVEPANEL);
+ _saveButton = createResource( _sprites.button, 3, 0, 29, 129, 48, SAVE_A_GAME, SAVEPANEL);
+ _downFastButton = createResource(_sprites.buttonDown, 1, 0, 212, 104, 0, SHIFT_DOWN_FAST, SAVEPANEL);
+ _downSlowButton = createResource(_sprites.buttonDown, 1, 0, 212, 114, 0, SHIFT_DOWN_SLOW, SAVEPANEL);
+ _upFastButton = createResource(_sprites.buttonDown, 1, 0, 212, 21, 0, SHIFT_UP_FAST, SAVEPANEL);
+ _upSlowButton = createResource(_sprites.buttonDown, 1, 0, 212, 10, 0, SHIFT_UP_SLOW, SAVEPANEL);
+ _quitButton = createResource( _sprites.button, 3, 0, 72, 129, 49, SP_CANCEL, SAVEPANEL);
+ _restoreButton = createResource( _sprites.button, 3, 0, 29, 129, 51, RESTORE_A_GAME, SAVEPANEL);
+
+ _savePanLookList[0] = _saveButton;
+ _restorePanLookList[0] = _restoreButton;
+ _restorePanLookList[1] = _savePanLookList[1] = _downSlowButton;
+ _restorePanLookList[2] = _savePanLookList[2] = _downFastButton;
+ _restorePanLookList[3] = _savePanLookList[3] = _upFastButton;
+ _restorePanLookList[4] = _savePanLookList[4] = _upSlowButton;
+ _restorePanLookList[5] = _savePanLookList[5] = _quitButton;
+}
+
+void SkyControl::buttonControl(SkyConResource *pButton) {
+
+ if (pButton == NULL) {
+ if (_textSprite) free(_textSprite);
+ _textSprite = NULL;
+ _curButtonText = 0;
+ _text->setSprite(NULL);
+ return ;
+ }
+ if (_curButtonText != pButton->_text) {
+ if (_textSprite) free(_textSprite);
+ _textSprite = NULL;
+ _curButtonText = pButton->_text;
+ if (pButton->_text) {
+ _skyText->getText(pButton->_text);
+ displayText_t textRes;
+ textRes = _skyText->displayText(NULL, false, PAN_LINE_WIDTH, 255);
+ _textSprite = (dataFileHeader*)textRes.textData;
+ _text->setSprite(_textSprite);
+ } else _text->setSprite(NULL);
+ }
+ _text->setXY(_mouseX + 12, _mouseY - 16);
+}
+
+void SkyControl::animClick(SkyConResource *pButton) {
+
+ if (pButton->_curSprite != pButton->_numSprites -1) {
+ pButton->_curSprite++;
+ pButton->drawToScreen(NO_MASK);
+ _system->update_screen();
+ delay(150);
+ pButton->_curSprite--;
+ pButton->drawToScreen(NO_MASK);
+ _system->update_screen();
+ }
+}
+
+void SkyControl::drawMainPanel(void) {
+
+ memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
+ _system->copy_rect(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+ _controlPanel->drawToScreen(NO_MASK);
+ _exitButton->drawToScreen(NO_MASK);
+ _savePanButton->drawToScreen(NO_MASK);
+ _restorePanButton->drawToScreen(NO_MASK);
+ _dosPanButton->drawToScreen(NO_MASK);
+ _restartPanButton->drawToScreen(NO_MASK);
+ _fxPanButton->drawToScreen(NO_MASK);
+ _musicPanButton->drawToScreen(NO_MASK);
+ _slode->drawToScreen(WITH_MASK);
+ _slide->drawToScreen(WITH_MASK);
+ _slide2->drawToScreen(WITH_MASK);
+ _bodge->drawToScreen(WITH_MASK);
+}
+
+void SkyControl::doControlPanel(void) {
+
+ if (SkyState::isDemo() && (!SkyState::isCDVersion())) {
+ return ;
+ }
+ initPanel();
+
+ _skyScreen->clearScreen();
+ _skyScreen->setPalette(60510);
+
+ drawMainPanel();
+
+ _skyMouse->spriteMouse(MOUSE_NORMAL,0,0);
+ bool quitPanel = false;
+ _lastButton = -1;
+ _curButtonText = 0;
+ _textSprite = NULL;
+ uint16 clickRes = 0;
+
+ while (!quitPanel) {
+ _text->drawToScreen(WITH_MASK);
+ _system->update_screen();
+ _mouseClicked = false;
+ delay(50);
+ if (_keyPressed == 27) { // escape pressed
+ _mouseClicked = false;
+ quitPanel = true;
+ }
+ bool haveButton = false;
+ for (uint8 lookCnt = 0; lookCnt < 9; lookCnt++) {
+ if (_controlPanLookList[lookCnt]->isMouseOver(_mouseX, _mouseY)) {
+ haveButton = true;
+ buttonControl(_controlPanLookList[lookCnt]);
+ if (_mouseClicked && _controlPanLookList[lookCnt]->_onClick) {
+ clickRes = handleClick(_controlPanLookList[lookCnt]);
+ buttonControl(NULL);
+ _text->drawToScreen(WITH_MASK); // flush text restore buffer
+ drawMainPanel();
+ if (clickRes == QUIT_PANEL) quitPanel = true;
+ }
+ _mouseClicked = false;
+ }
+ }
+ if (!haveButton) buttonControl(NULL);
+
+ }
+ memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
+ _system->copy_rect(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+ _system->update_screen();
+ _skyScreen->forceRefresh();
+ _skyScreen->setPalette((uint8*)SkyState::fetchCompact(SkyState::_systemVars.currentPalette));
+ removePanel();
+}
+
+uint16 SkyControl::handleClick(SkyConResource *pButton) {
+
+ switch(pButton->_onClick) {
+ case DO_NOTHING:
+ return 0;
+
+ case REST_GAME_PANEL:
+ animClick(pButton);
+ return saveRestorePanel(false); // texts can't be edited
+
+ case SAVE_GAME_PANEL:
+ animClick(pButton);
+ return saveRestorePanel(true); // texts can be edited
+
+ case SAVE_A_GAME:
+ animClick(pButton);
+ return GAME_SAVED;
+
+ case RESTORE_A_GAME:
+ animClick(pButton);
+ return GAME_RESTORED;
+
+ case SP_CANCEL:
+ animClick(pButton);
+ return CANCEL_PRESSED;
+
+ case SHIFT_DOWN_FAST:
+ animClick(pButton);
+ return shiftDown(FAST);
+
+ case SHIFT_DOWN_SLOW:
+ animClick(pButton);
+ return shiftDown(SLOW);
+
+ case SHIFT_UP_FAST:
+ animClick(pButton);
+ return shiftUp(FAST);
+
+ case SHIFT_UP_SLOW:
+ animClick(pButton);
+ return shiftUp(SLOW);
+
+ case SPEED_SLIDE:
+ return 0;
+
+ case MUSIC_SLIDE:
+ _mouseClicked = true;
+ return doMusicSlide();
+
+ case TOGGLE_FX:
+ return toggleFx(pButton);
+
+ case TOGGLE_MS:
+ return 0;
+
+ case EXIT:
+ animClick(pButton);
+ return QUIT_PANEL;
+
+ case RESTART:
+ animClick(pButton);
+ return 0;
+
+ case QUIT_TO_DOS:
+ animClick(pButton);
+ return 0;
+
+ default:
+ error("SkyControl::handleClick: unknown routine: %X\n",pButton->_onClick);
+ }
+}
+
+uint16 SkyControl::doMusicSlide(void) {
+
+ int ofsY = _slide2->_y - _mouseY;
+ uint8 volume;
+ while (_mouseClicked) {
+ delay(50);
+ int newY = ofsY + _mouseY;
+ if (newY < 59) newY = 59;
+ if (newY > 91) newY = 91;
+ if (newY != _slide2->_y) {
+ _slode->drawToScreen(NO_MASK);
+ _slide2->setXY(_slide2->_x, (uint16)newY);
+ _slide2->drawToScreen(WITH_MASK);
+ _slide->drawToScreen(WITH_MASK);
+ volume = (newY - 59) * 4;
+ if (volume >= 128) volume = 0;
+ else volume = 127 - volume;
+ _skyMusic->setVolume(volume);
+ }
+ buttonControl(_slide2);
+ _text->drawToScreen(WITH_MASK);
+ _system->update_screen();
+ }
+ return 0;
+}
+
+uint16 SkyControl::toggleFx(SkyConResource *pButton) {
+
+ SkyState::_systemVars.systemFlags ^= SF_FX_OFF;
+ if (SkyState::_systemVars.systemFlags & SF_FX_OFF) {
+ pButton->_curSprite = 0;
+ pButton->_text = 0x7000 + 86;
+ } else {
+ pButton->_curSprite = 2;
+ pButton->_text = 0x7000 + 87;
+ }
+ pButton->drawToScreen(WITH_MASK);
+ buttonControl(pButton);
+ _system->update_screen();
+ return TOGGLED;
+}
+
+uint16 SkyControl::shiftDown(uint8 speed) {
+
+ if (speed == SLOW) {
+ if (_firstText >= MAX_SAVE_GAMES - MAX_ON_SCREEN) return 0;
+ _firstText++;
+ } else {
+ if (_firstText <= MAX_SAVE_GAMES - 2 * MAX_ON_SCREEN)
+ _firstText += MAX_ON_SCREEN;
+ else if (_firstText < MAX_SAVE_GAMES - MAX_ON_SCREEN)
+ _firstText = MAX_SAVE_GAMES - MAX_ON_SCREEN;
+ else return 0;
+ }
+ return SHIFTED;
+}
+
+uint16 SkyControl::shiftUp(uint8 speed) {
+
+ if (speed == SLOW) {
+ if (_firstText > 0) _firstText--;
+ else return 0;
+ } else {
+ if (_firstText >= MAX_ON_SCREEN) _firstText -= MAX_ON_SCREEN;
+ else if (_firstText > 0) _firstText = 0;
+ else return 0;
+ }
+ return SHIFTED;
+}
+
+uint16 SkyControl::saveRestorePanel(bool allowEdit) {
+
+ buttonControl(NULL);
+ _text->drawToScreen(WITH_MASK); // flush text restore buffer
+
+ SkyConResource **lookList;
+ uint16 cnt;
+ if (allowEdit) lookList = _savePanLookList;
+ else lookList = _restorePanLookList;
+
+ uint8 *saveGameTexts = (uint8*)malloc(MAX_SAVE_GAMES * MAX_TEXT_LEN);
+ dataFileHeader *textSprites[MAX_ON_SCREEN];
+ _firstText = 0;
+
+ _savePanel->drawToScreen(NO_MASK);
+ _quitButton->drawToScreen(NO_MASK);
+
+ loadSaveDescriptions(saveGameTexts);
+ setUpGameSprites(saveGameTexts, textSprites, _firstText);
+
+ uint16 selectedGame = 0;
+
+ bool quitPanel = false;
+ bool refreshNames = true;
+ uint16 clickRes;
+ while (!quitPanel) {
+ if (refreshNames) {
+ showSprites(textSprites);
+ refreshNames = false;
+ }
+
+ _text->drawToScreen(WITH_MASK);
+ _system->update_screen();
+ _mouseClicked = false;
+ delay(50);
+ if (_keyPressed == 27) { // escape pressed
+ _mouseClicked = false;
+ clickRes = CANCEL_PRESSED;
+ quitPanel = true;
+ }
+ bool haveButton = false;
+ for (uint16 cnt = 0; cnt < 6; cnt++)
+ if (lookList[cnt]->isMouseOver(_mouseX, _mouseY)) {
+ buttonControl(lookList[cnt]);
+ haveButton = true;
+
+ if (_mouseClicked && lookList[cnt]->_onClick) {
+ _mouseClicked = false;
+
+ clickRes = handleClick(lookList[cnt]);
+ if ((clickRes == CANCEL_PRESSED) || (clickRes == GAME_SAVED) ||
+ (clickRes == GAME_RESTORED) || (clickRes == NO_DISK_SPACE))
+ quitPanel = true;
+ if (clickRes == SHIFTED) {
+ setUpGameSprites(saveGameTexts, textSprites, _firstText);
+ refreshNames = true;
+ }
+ }
+ }
+ if (_mouseClicked) {
+ if ((_mouseX >= GAME_NAME_X) && (_mouseX <= GAME_NAME_X + PAN_LINE_WIDTH) &&
+ (_mouseY >= GAME_NAME_Y) && (_mouseY <= GAME_NAME_Y + PAN_CHAR_HEIGHT * MAX_ON_SCREEN)) {
+
+ selectedGame = (_mouseY - GAME_NAME_Y) / PAN_CHAR_HEIGHT + _firstText;
+ }
+ }
+ if (!haveButton) buttonControl(NULL);
+
+ }
+
+ for (cnt = 0; cnt < MAX_ON_SCREEN; cnt++)
+ free(textSprites[cnt]);
+
+ free(saveGameTexts);
+
+ return clickRes;
+}
+
+void SkyControl::setUpGameSprites(uint8 *nameBuf, dataFileHeader **nameSprites, uint16 firstNum) {
+
+ nameBuf += firstNum * MAX_TEXT_LEN;
+
+ for (uint16 cnt = 0; cnt < MAX_ON_SCREEN; cnt++) {
+ displayText_t textSpr = _skyText->displayText((char*)nameBuf, NULL, false, PAN_LINE_WIDTH, 37);
+ nameBuf += MAX_TEXT_LEN;
+ nameSprites[cnt] = (dataFileHeader*)textSpr.textData;
+ }
+}
+
+void SkyControl::showSprites(dataFileHeader **nameSprites) {
+
+ SkyConResource *drawResource = new SkyConResource(NULL, 1, 0, 0, 0, 0, 0, _system, _screenBuf);
+ for (uint16 cnt = 0; cnt < MAX_ON_SCREEN; cnt++) {
+ drawResource->setSprite(nameSprites[cnt]);
+ drawResource->setXY(GAME_NAME_X, GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT);
+ drawResource->drawToScreen(NO_MASK);
+ }
+ delete drawResource;
+}
+
+void SkyControl::loadSaveDescriptions(uint8 *destBuf) {
+
+ memset(destBuf, 0, MAX_SAVE_GAMES * MAX_TEXT_LEN);
+
+ File *inf = new File();
+ inf->open("SKY.SAV",_savePath);
+ if (inf->isOpen()) {
+ uint8 *tmpBuf = (uint8*)malloc(inf->size());
+ inf->read(tmpBuf, inf->size());
+ uint8 *destPos = destBuf;
+ uint8 *inPos = tmpBuf;
+ for (uint16 cnt = 0; cnt < MAX_SAVE_GAMES; cnt++) {
+ sprintf((char*)destPos,"%3d: ", cnt + 1);
+ uint8 nameCnt = 0;
+ while (destPos[nameCnt + 5] = inPos[nameCnt]) nameCnt++;
+ destPos += MAX_TEXT_LEN;
+ }
+ free(tmpBuf);
+ inf->close();
+ } else {
+ uint8 *destPos = destBuf;
+ for (uint16 cnt = 0; cnt < MAX_SAVE_GAMES; cnt++) {
+ sprintf((char*)destPos,"%3d: ", cnt + 1);
+ destPos += MAX_TEXT_LEN;
+ }
+ }
+}
+
+void SkyControl::delay(unsigned int amount) {
+
+ OSystem::Event event;
+
+ uint32 start = _system->get_msecs();
+ uint32 cur = start;
+ _keyPressed = 0; //reset
+
+ do {
+ while (_system->poll_event(&event)) {
+ switch (event.event_code) {
+ case OSystem::EVENT_KEYDOWN:
+ // Make sure backspace works right (this fixes a small issue on OS X)
+ if (event.kbd.keycode == 8)
+ _keyPressed = 8;
+ else
+ _keyPressed = (byte)event.kbd.ascii;
+ break;
+
+ case OSystem::EVENT_MOUSEMOVE:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _system->set_mouse_pos(_mouseX, _mouseY);
+ break;
+
+ case OSystem::EVENT_LBUTTONDOWN:
+ _mouseClicked = true;
+#ifdef _WIN32_WCE
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+#endif
+ break;
+
+ case OSystem::EVENT_LBUTTONUP:
+ _mouseClicked = false;
+ break;
+
+ case OSystem::EVENT_RBUTTONDOWN:
+ break;
+
+ case OSystem::EVENT_QUIT:
+ _system->quit();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ uint this_delay = 20; // 1?
+ if (this_delay > amount)
+ this_delay = amount;
+
+ if (this_delay > 0) _system->delay_msecs(this_delay);
+
+ cur = _system->get_msecs();
+ } while (cur < start + amount);
+}
diff --git a/sky/control.h b/sky/control.h
new file mode 100644
index 0000000000..d8ef8d621f
--- /dev/null
+++ b/sky/control.h
@@ -0,0 +1,194 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef CONTROL_H
+#define CONTROL_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "sky/struc.h"
+#include "common/engine.h"
+#include "sky/screen.h"
+#include "sky/disk.h"
+#include "sky/mouse.h"
+
+#define MAX_SAVE_GAMES 999
+#define MAX_TEXT_LEN 80
+#define PAN_LINE_WIDTH 184
+#define PAN_CHAR_HEIGHT 12
+#define MPNL_X 60 // Main Panel
+#define MPNL_Y 10
+
+#define SPNL_X 20 // Save Panel
+#define SPNL_Y 20
+#define SP_HEIGHT 149
+#define SP_TOP_GAP 12
+#define SP_BOT_GAP 27
+
+#define GAME_NAME_X (SPNL_X + 18) // x coordinate of game names
+#define GAME_NAME_Y (SPNL_Y + SP_TOP_GAP) // start y coord of game names
+#define MAX_ON_SCREEN ((SP_HEIGHT - SP_TOP_GAP - SP_BOT_GAP) / PAN_CHAR_HEIGHT) // no of save games on screen
+#define CP_PANEL 60400 // main panel sprite
+
+#define CHARACTER_LIST " ,().='-&+!?\"" // list of allowed characters
+
+#define MAINPANEL 0
+#define SAVEPANEL 1
+
+#define NO_MASK false
+#define WITH_MASK true
+
+// resource's onClick routines
+#define DO_NOTHING 0
+#define REST_GAME_PANEL 1
+#define SAVE_GAME_PANEL 2
+#define SAVE_A_GAME 3
+#define RESTORE_A_GAME 4
+#define SP_CANCEL 5
+#define SHIFT_DOWN_FAST 6
+#define SHIFT_DOWN_SLOW 7
+#define SHIFT_UP_FAST 8
+#define SHIFT_UP_SLOW 9
+#define SPEED_SLIDE 10
+#define MUSIC_SLIDE 11
+#define TOGGLE_FX 12
+#define TOGGLE_MS 13
+#define EXIT 14
+#define RESTART 15
+#define QUIT_TO_DOS 16
+
+// onClick return codes
+#define CANCEL_PRESSED 100
+#define NAME_TOO_SHORT 101
+#define GAME_SAVED 102
+#define SHIFTED 103
+#define TOGGLED 104
+#define RESTARTED 105
+#define GAME_RESTORED 106
+#define RESTORE_FAILED 107
+#define NO_DISK_SPACE 108
+#define SPEED_CHANGED 109
+#define QUIT_PANEL 110
+
+#define SLOW 0
+#define FAST 1
+
+class SkyConResource {
+public:
+ SkyConResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen);
+ virtual ~SkyConResource(void) {};
+ void setSprite(void *pSpData) { _spriteData = (dataFileHeader*)pSpData; };
+ void setText(uint32 pText) { if (pText) _text = pText + 0x7000; else _text = 0; };
+ void setXY(uint16 x, uint16 y) { _x = x; _y = y; };
+ bool isMouseOver(uint32 mouseX, uint32 mouseY);
+ virtual void drawToScreen(bool doMask);
+
+ dataFileHeader *_spriteData;
+ uint32 _numSprites, _curSprite;
+ uint16 _x, _y;
+ uint32 _text;
+ uint8 _onClick;
+ OSystem *_system;
+ uint8 *_screen;
+private:
+};
+
+class SkyTextResource : public SkyConResource {
+public:
+ SkyTextResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen);
+ virtual ~SkyTextResource(void);
+ virtual void drawToScreen(bool doMask);
+private:
+ uint16 _oldX, _oldY;
+ uint8 *_oldScreen;
+};
+
+class SkyControl {
+public:
+ SkyControl(SkyScreen *screen, SkyDisk *disk, SkyMouse *mouse, SkyText *text, SkyMusicBase *music, OSystem *system, const char *savePath);
+ void doControlPanel(void);
+
+private:
+ void initPanel(void);
+ void removePanel(void);
+ void drawMainPanel(void);
+ void delay(unsigned int amount);
+ void buttonControl(SkyConResource *pButton);
+ void loadSaveDescriptions(uint8 *destBuf);
+ void setUpGameSprites(uint8 *nameBuf, dataFileHeader **nameSprites, uint16 firstNum);
+ void showSprites(dataFileHeader **nameSprites);
+ void animClick(SkyConResource *pButton);
+ uint16 doMusicSlide(void);
+ uint16 handleClick(SkyConResource *pButton);
+ uint16 toggleFx(SkyConResource *pButton);
+ uint16 shiftDown(uint8 speed);
+ uint16 shiftUp(uint8 speed);
+ const char *_savePath;
+
+ uint16 saveRestorePanel(bool allowEdit);
+
+ SkyScreen *_skyScreen;
+ SkyDisk *_skyDisk;
+ SkyMouse *_skyMouse;
+ SkyText *_skyText;
+ SkyMusicBase *_skyMusic;
+ OSystem *_system;
+ int _mouseX, _mouseY;
+ bool _mouseClicked;
+ byte _keyPressed;
+
+ SkyConResource *createResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, int16 pX, int16 pY, uint32 pText, uint8 pOnClick, uint8 panelType);
+
+ struct {
+ uint8 *controlPanel;
+ uint8 *button;
+ uint8 *buttonDown;
+ uint8 *savePanel;
+ uint8 *yesNo;
+ uint8 *slide;
+ uint8 *slode;
+ uint8 *slode2;
+ uint8 *slide2;
+ uint8 *musicBodge;
+ } _sprites;
+
+ uint8 *_screenBuf;
+ int _lastButton;
+ uint32 _curButtonText;
+ uint16 _firstText;
+
+ dataFileHeader *_textSprite;
+ SkyTextResource *_text;
+
+ SkyConResource *_controlPanel, *_exitButton, *_slide, *_slide2, *_slode;
+ SkyConResource *_restorePanButton, *_savePanButton, *_dosPanButton, *_restartPanButton, *_fxPanButton, *_musicPanButton;
+ SkyConResource *_bodge, *_yesNo;
+ SkyConResource *_controlPanLookList[9];
+
+ //- Save/restore panel
+ SkyConResource *_savePanel;
+ SkyConResource *_saveButton, *_downFastButton, *_downSlowButton;
+ SkyConResource *_upFastButton, *_upSlowButton, *_quitButton, *_restoreButton;
+
+ SkyConResource *_savePanLookList[6], *_restorePanLookList[6];
+};
+
+#endif // CONTROL_H
diff --git a/sky/logic.cpp b/sky/logic.cpp
index 4510c1aba0..5718aefa57 100644
--- a/sky/logic.cpp
+++ b/sky/logic.cpp
@@ -2292,6 +2292,7 @@ bool SkyLogic::fnFadeDown(uint32 a, uint32 b, uint32 c) {
}
bool SkyLogic::fnFadeUp(uint32 a, uint32 b, uint32 c) {
+ SkyState::_systemVars.currentPalette = a;
_skyScreen->fnFadeUp(a,b);
return true;
}
diff --git a/sky/module.mk b/sky/module.mk
index 1ca2fd56a6..efb2a8d01d 100644
--- a/sky/module.mk
+++ b/sky/module.mk
@@ -16,10 +16,12 @@ MODULE_OBJS = \
sky/sound.o \
sky/text.o \
sky/introimg.o \
+ sky/control.o \
sky/music/adlibchannel.o \
sky/music/adlibmusic.o \
sky/music/gmchannel.o \
sky/music/gmmusic.o \
+ sky/music/mt32music.o \
sky/music/musicbase.o \
# Include common rules
diff --git a/sky/music/adlibmusic.cpp b/sky/music/adlibmusic.cpp
index 46b72e7f03..827ffa8743 100644
--- a/sky/music/adlibmusic.cpp
+++ b/sky/music/adlibmusic.cpp
@@ -44,6 +44,12 @@ SkyAdlibMusic::~SkyAdlibMusic(void) {
YM3812Shutdown();
}
+void SkyAdlibMusic::setVolume(uint8 volume) {
+
+ _musicVolume = volume;
+ _mixer->setMusicVolume(_musicVolume << 1);
+}
+
void SkyAdlibMusic::premixerCall(int16 *buf, uint len) {
if (_musicData == NULL) {
diff --git a/sky/music/adlibmusic.h b/sky/music/adlibmusic.h
index 4fb8fea7fb..8a1bb2c169 100644
--- a/sky/music/adlibmusic.h
+++ b/sky/music/adlibmusic.h
@@ -33,6 +33,7 @@ class SkyAdlibMusic : public SkyMusicBase {
public:
SkyAdlibMusic(SoundMixer *pMixer, SkyDisk *pSkyDisk);
~SkyAdlibMusic(void);
+ virtual void setVolume(uint8 volume);
private:
SoundMixer *_mixer;
uint8 *_initSequence;
diff --git a/sky/music/gmmusic.cpp b/sky/music/gmmusic.cpp
index 92ea1e4954..78bf349a04 100644
--- a/sky/music/gmmusic.cpp
+++ b/sky/music/gmmusic.cpp
@@ -47,6 +47,16 @@ SkyGmMusic::~SkyGmMusic(void) {
delete _midiDrv;
}
+void SkyGmMusic::setVolume(uint8 volume) {
+
+ uint8 sysEx[6];
+ _musicVolume = volume;
+ if (volume > 0) volume = (volume * 2) / 3 + 43; // GM synths behave kinda logarithmic
+ sysEx[0] = 0x7F; sysEx[1] = 0x7F; sysEx[2] = 0x04; sysEx[3] = 0x01;
+ sysEx[4] = 0; sysEx[5] = volume & 0x7F;
+ _midiDrv->sysEx(sysEx, 6);
+}
+
void SkyGmMusic::timerCall(void) {
// midi driver polls hundred times per sec. We only want 50 times.
diff --git a/sky/music/gmmusic.h b/sky/music/gmmusic.h
index b3dca05b39..6c9cd0b25c 100644
--- a/sky/music/gmmusic.h
+++ b/sky/music/gmmusic.h
@@ -32,6 +32,7 @@ class SkyGmMusic : public SkyMusicBase {
public:
SkyGmMusic(MidiDriver *pMidiDrv, SkyDisk *pSkyDisk);
~SkyGmMusic(void);
+ virtual void setVolume(uint8 volume);
private:
static void passTimerFunc(void *param);
void timerCall(void);
diff --git a/sky/music/mt32music.cpp b/sky/music/mt32music.cpp
index 03f3c80a77..1a9b167438 100644
--- a/sky/music/mt32music.cpp
+++ b/sky/music/mt32music.cpp
@@ -58,6 +58,15 @@ void SkyMT32Music::timerCall(void) {
pollMusic();
}
+void SkyMT32Music::setVolume(uint8 volume) {
+
+ uint8 sysEx[6];
+ _musicVolume = volume;
+ sysEx[0] = 0x7F; sysEx[1] = 0x7F; sysEx[2] = 0x04; sysEx[3] = 0x01;
+ sysEx[4] = 0; sysEx[5] = volume & 0x7F;
+ _midiDrv->sysEx(sysEx, 6);
+}
+
void SkyMT32Music::setupPointers(void) {
_musicDataLoc = (_musicData[0x7DD] << 8) | _musicData[0x7DC];
@@ -78,70 +87,50 @@ void SkyMT32Music::setupChannels(uint8 *channelData) {
bool SkyMT32Music::processPatchSysEx(uint8 *sysExData) {
+ uint8 sysExBuf[15];
uint8 crc = 0;
if (sysExData[0] & 0x80) return false;
- uint8 patchNum = sysExData[0];
- sysExData++;
- uint8 timbreGroup = sysExData[0] >> 6;
- uint8 timbreNumber = sysExData[0] & 0x3F;
- uint8 keyShift = sysExData[1] & 0x3F;
- uint8 fineTune = sysExData[2] & 0x7F;
- uint8 benderRange = sysExData[3] & 0x7F;
- uint8 assignMode = sysExData[1] >> 6;
- uint8 reverbSwitch = sysExData[2] >> 7;
-
- _midiDrv->send(MIDI_PACK(0xF0, 0x41, 0x10, 0x16));
- _midiDrv->send(MIDI_PACK(0x12, 5, patchNum >> 4, (patchNum & 0xF) << 3));
-
- crc -= 5 + (patchNum >> 4) + ((patchNum & 0xF) << 3);
- crc -= timbreGroup + timbreNumber + keyShift + fineTune;
- crc -= benderRange + assignMode + reverbSwitch;
-
- _midiDrv->send(MIDI_PACK(timbreGroup, timbreNumber, keyShift, fineTune));
- _midiDrv->send(MIDI_PACK(benderRange, assignMode, reverbSwitch, crc));
- _midiDrv->send(0xF7);
-
- debug(3," Patch %02X:\n",patchNum);
- debug(3," Timbre Group: %d\n",timbreGroup);
- debug(3," Timbre Number: %d\n",timbreNumber);
- debug(3," Key Shift: %d\n",keyShift);
- debug(3," Fine Tune: %d\n",fineTune);
- debug(3," Bender Range: %d\n",benderRange);
- debug(3," Assign Mode: %d\n",assignMode);
- debug(3," Reverb Switch: %d\n\n",reverbSwitch);
+ // decompress data from stream
+ sysExBuf[0] = 0x41; sysExBuf[1] = 0x10; sysExBuf[2] = 0x16; sysExBuf[3] = 0x12; sysExBuf[4] = 0x5;
+ sysExBuf[5] = sysExData[0] >> 4; // patch offset part 1
+ sysExBuf[6] = (sysExData[0] & 0xF) << 3; // patch offset part 2
+ sysExBuf[7] = sysExData[1] >> 6; // timbre group
+ sysExBuf[8] = sysExData[1] & 0x3F; // timbre num
+ sysExBuf[9] = sysExData[2] & 0x3F; // key shift
+ sysExBuf[10] = sysExData[3] & 0x7F; // fine tune
+ sysExBuf[11] = sysExData[4] & 0x7F; // bender range
+ sysExBuf[12] = sysExData[2] >> 6; // assign mode
+ sysExBuf[13] = sysExData[3] >> 7; // reverb switch
+ for (uint8 cnt = 4; cnt < 14; cnt++)
+ crc -= sysExBuf[cnt];
+ sysExBuf[14] = crc; // crc
+ _midiDrv->sysEx(sysExBuf, 15);
return true;
}
void SkyMT32Music::startDriver(void) {
- _midiDrv->send(0xFF); // reset midi device
-
// setup timbres and patches using SysEx data
uint8* sysExData = _sysExSequence;
uint8 timbreNum = sysExData[0];
uint8 cnt, crc;
- uint32 sysComb;
sysExData++;
+ uint8 sendBuf[256];
+ uint8 len;
+ sendBuf[0] = 0x41; sendBuf[1] = 0x10; sendBuf[2] = 0x16; sendBuf[3] = 0x12;
for (cnt = 0; cnt < timbreNum; cnt++) {
+ len = 7;
crc = 0;
- _midiDrv->send(MIDI_PACK(0xF0, 0x41, 0x10, 0x16));
- //- sendTimbreAddress
- sysComb = (0x2 << 16) | (sysExData[0] << 8) | 0xA;
+ // Timbre address
+ sendBuf[4] = 0x8 | (sysExData[0] >> 6);
+ sendBuf[5] = (sysExData[0] & 0x3F) << 1;
+ sendBuf[6] = 0xA;
sysExData++;
- uint8 sysByte1 = (uint8)(sysComb >> 14);
- uint8 sysByte2 = (uint8)((sysComb & 0x3FFF) >> 7);
- uint8 sysByte3 = (uint8)(sysComb & 0x7F);
- _midiDrv->send(MIDI_PACK(0x12, sysByte1, sysByte2, sysByte3));
- debug(3,"InitBySysEx: Timbre address: %02X:%02X:%02X (%02X)\n",sysByte1,sysByte2,sysByte3,(sysExData-1)[0]);
- crc -= sysByte1 + sysByte2 + sysByte3;
- //- sendTimbreData
+ crc -= sendBuf[4] + sendBuf[5] + sendBuf[6];
uint8 dataLen = sysExData[0];
- debug(3,"[%02X]",dataLen);
sysExData++;
- uint32 nextSend = 0;
- uint8 bytesInSend = 0;
- debug(3," Timbre Data:");
+ // Timbre data:
do {
uint8 rlVal = 1;
uint8 codeVal = sysExData[0];
@@ -154,27 +143,15 @@ void SkyMT32Music::startDriver(void) {
dataLen--;
}
for (uint8 cnt = 0; cnt < rlVal; cnt++) {
- nextSend |= codeVal << (bytesInSend << 3);
+ sendBuf[len] = codeVal;
+ len++;
crc -= codeVal;
- debug(3," %02X",codeVal);
- bytesInSend++;
- if (bytesInSend == 4) {
- _midiDrv->send(nextSend);
- nextSend = bytesInSend = 0;
- }
}
dataLen--;
} while (dataLen > 0);
- crc &= 0x7F;
- debug(3," %02X F7\n",crc);
- nextSend |= crc << (bytesInSend << 3);
- bytesInSend++;
- if (bytesInSend == 4) {
- _midiDrv->send(nextSend);
- nextSend = bytesInSend = 0;
- }
- nextSend |= 0xF7 << (bytesInSend << 3);
- _midiDrv->send(nextSend);
+ sendBuf[len] = crc & 0x7F;
+ len++;
+ _midiDrv->sysEx(sendBuf, len);
}
while (processPatchSysEx(sysExData))
diff --git a/sky/music/mt32music.h b/sky/music/mt32music.h
index 76b2a18fc5..e28d3d5373 100644
--- a/sky/music/mt32music.h
+++ b/sky/music/mt32music.h
@@ -36,6 +36,7 @@ private:
static void passTimerFunc(void *param);
void timerCall(void);
bool processPatchSysEx(uint8 *sysExData);
+ virtual void setVolume(uint8 volume);
bool _ignoreNextPoll;
uint8 *_sysExSequence;
diff --git a/sky/music/musicbase.cpp b/sky/music/musicbase.cpp
index d03edbb4f2..da872f6cf1 100644
--- a/sky/music/musicbase.cpp
+++ b/sky/music/musicbase.cpp
@@ -43,7 +43,7 @@ void SkyMusicBase::loadSection(uint8 pSection)
_allowedCommands = 0;
_musicTempo0 = 0x78; // init constants taken from idb file, area ~0x1060
_musicTempo1 = 0xC0;
- _musicVolume = 0x100;
+ _musicVolume = 127;
_onNextPoll.doReInit = false;
_onNextPoll.doStopMusic = false;
_onNextPoll.musicToProcess = 0;
diff --git a/sky/music/musicbase.h b/sky/music/musicbase.h
index cae59616a8..e237da9e71 100644
--- a/sky/music/musicbase.h
+++ b/sky/music/musicbase.h
@@ -48,6 +48,8 @@ public:
void loadSection(uint8 pSection);
void musicCommand(uint16 command);
void startMusic(uint16 param) { _onNextPoll.musicToProcess = param & 0xF; }; // 4
+ virtual void setVolume(uint8 volume) = 0;
+ uint8 giveVolume(void) { return (uint8)_musicVolume; };
protected:
diff --git a/sky/sky.cpp b/sky/sky.cpp
index 846e78fce2..666699f6f0 100644
--- a/sky/sky.cpp
+++ b/sky/sky.cpp
@@ -141,6 +141,10 @@ void SkyState::go() {
while (1) {
delay(50);
+ if ((_key_pressed == 27) || (_key_pressed == 63)) { // 27 = escape, 63 = F5
+ _key_pressed = 0;
+ _skyControl->doControlPanel();
+ }
_skyMouse->mouseEngine((uint16)_sdl_mouse_x, (uint16)_sdl_mouse_y);
_skyLogic->engine();
_skyScreen->recreate();
@@ -152,8 +156,6 @@ void SkyState::go() {
void SkyState::initialise(void) {
- //initialise_memory();
-
_skyDisk = new SkyDisk(_gameDataPath);
_skySound = new SkySound(_mixer, _skyDisk);
@@ -164,7 +166,10 @@ void SkyState::initialise(void) {
_skyMusic = new SkyAdlibMusic(_mixer, _skyDisk);
} else {
_systemVars.systemFlags |= SF_ROLAND;
- _skyMusic = new SkyGmMusic(_detector->createMidi(), _skyDisk);
+ if (_detector->_native_mt32)
+ _skyMusic = new SkyMT32Music(_detector->createMidi(), _skyDisk);
+ else
+ _skyMusic = new SkyGmMusic(_detector->createMidi(), _skyDisk);
}
_systemVars.systemFlags |= SF_PLAY_VOCS;
@@ -174,14 +179,14 @@ void SkyState::initialise(void) {
initVirgin();
initItemList();
- //initScript();
- //initialiseRouter();
loadFixedItems();
_skyLogic = new SkyLogic(_skyScreen, _skyDisk, _skyText, _skyMusic, _skyMouse, _skySound);
_skyMouse->useLogicInstance(_skyLogic);
_timer = Engine::_timer; // initialize timer *after* _skyScreen has been initialized.
_timer->installProcedure(&timerHandler, 1000000 / 50); //call 50 times per second
+
+ _skyControl = new SkyControl(_skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _system, getSavePath());
}
void SkyState::initItemList() {
diff --git a/sky/sky.h b/sky/sky.h
index 6fdcecd499..7eb7c1db08 100644
--- a/sky/sky.h
+++ b/sky/sky.h
@@ -37,6 +37,8 @@
#include "sky/music/gmmusic.h"
#include "sky/music/mt32music.h"
#include "sky/mouse.h"
+#include "sky/control.h"
+#include "common/config-file.h"
struct SystemVars {
uint32 systemFlags;
@@ -51,6 +53,7 @@ struct SystemVars {
class SkyLogic;
class SkyScreen;
+class SkyControl;
class SkyState : public Engine {
void errorString(const char *buf_input, char *buf_output);
@@ -82,6 +85,7 @@ protected:
SkyLogic *_skyLogic;
SkyMouse *_skyMouse;
SkyScreen *_skyScreen;
+ SkyControl *_skyControl;
SkyMusicBase *_skyMusic;
GameDetector *_detector; // necessary for music
diff --git a/sky/sound.cpp b/sky/sound.cpp
index ab7a866a63..b44cbc2fa8 100644
--- a/sky/sound.cpp
+++ b/sky/sound.cpp
@@ -1101,7 +1101,7 @@ void SkySound::fnPauseFx(void) {
}
bool SkySound::fnStartFx(uint32 sound) {
- if (sound < 256 || sound > MAX_FX_NUMBER || _sfxPaused)
+ if (sound < 256 || sound > MAX_FX_NUMBER || _sfxPaused || (SkyState::_systemVars.systemFlags & SF_FX_OFF))
return true;
uint8 screen = (uint8)(SkyLogic::_scriptVariables[SCREEN] & 0xff);