From 7f5df14e7d5a4b4c560fa8697994fa5b512f8971 Mon Sep 17 00:00:00 2001 From: Robert Göffringmann Date: Wed, 17 Dec 2003 05:16:37 +0000 Subject: menu, sound and mouse fixes. svn-id: r11701 --- sword1/logic.cpp | 2 -- sword1/menu.cpp | 44 ++++++++++++++++++++++++++++++++++---------- sword1/menu.h | 1 + sword1/mouse.cpp | 17 +++++++++++++++-- sword1/mouse.h | 5 ++++- sword1/sound.cpp | 34 +++++++++++++++++++++++++--------- sword1/sound.h | 3 +-- sword1/sword1.cpp | 6 ++++-- 8 files changed, 84 insertions(+), 28 deletions(-) diff --git a/sword1/logic.cpp b/sword1/logic.cpp index 83f7bde9e3..360d9e0f21 100644 --- a/sword1/logic.cpp +++ b/sword1/logic.cpp @@ -850,7 +850,6 @@ int SwordLogic::fnFullSetFrame(BsObject *cpt, int32 id, int32 cdt, int32 spr, in } int SwordLogic::fnFadeDown(BsObject *cpt, int32 id, int32 speed, int32 d, int32 e, int32 f, int32 z, int32 x) { - warning("fnFadeDown speed = %d", speed); _screen->fadeDownPalette(); return SCRIPT_CONT; } @@ -1484,7 +1483,6 @@ int SwordLogic::fnGetPos(BsObject *cpt, int32 id, int32 targetId, int32 b, int32 if (target->o_status & STAT_SHRINK) { int32 scale = (target->o_scale_a * target->o_ycoord + target->o_scale_b) / 256; _scriptVars[RETURN_VALUE_4] = (megaSeperation * scale) / 256; - debug(1, "fnGetPos: scaled megaSeperation = %d", _scriptVars[RETURN_VALUE_4]); } else _scriptVars[RETURN_VALUE_4] = megaSeperation; return SCRIPT_CONT; diff --git a/sword1/menu.cpp b/sword1/menu.cpp index f7249c7fc0..bbe993201d 100644 --- a/sword1/menu.cpp +++ b/sword1/menu.cpp @@ -39,7 +39,9 @@ SwordMenuIcon::SwordMenuIcon(uint8 menuType, uint8 menuPos, uint32 resId, uint32 } bool SwordMenuIcon::wasClicked(uint16 mouseX, uint16 mouseY) { - if ((mouseY > 440) && (mouseX >= _menuPos * 40) && (mouseX < (_menuPos + 1) * 40)) + if (((_menuType == MENU_TOP) && (mouseY >= 40)) || ((_menuType == MENU_BOT) && (mouseY < 440))) + return false; + if ((mouseX >= _menuPos * 40) && (mouseX < (_menuPos + 1) * 40)) return true; else return false; @@ -79,18 +81,29 @@ uint8 SwordMenu::checkMenuClick(uint8 menuType) { if (mouseEvent & BS1L_BUTTON_DOWN) { SwordLogic::_scriptVars[OBJECT_HELD] = _subjectBar[cnt]; buildSubjects(); - return 0; } else if (mouseEvent & BS1L_BUTTON_UP) { if (SwordLogic::_scriptVars[OBJECT_HELD] == _subjectBar[cnt]) return cnt + 1; else { SwordLogic::_scriptVars[OBJECT_HELD] = 0; buildSubjects(); - return 0; } } } else { - return 0; + for (uint8 cnt = 0; cnt < _inMenu; cnt++) { + if (_objects[cnt]->wasClicked(x, y)) + if (mouseEvent & BS1L_BUTTON_DOWN) { + SwordLogic::_scriptVars[OBJECT_HELD] = _menuList[cnt]; + buildMenu(); + } else if (mouseEvent & BS1L_BUTTON_UP) { + if (SwordLogic::_scriptVars[OBJECT_HELD] == _menuList[cnt]) { + return cnt + 1; + } else { + SwordLogic::_scriptVars[OBJECT_HELD] = 0; + buildMenu(); + } + } + } } return 0; } @@ -120,7 +133,7 @@ void SwordMenu::buildMenu(void) { _inMenu = 0; for (uint32 pocketNo = 0; pocketNo < TOTAL_pockets; pocketNo++) if (pockets[pocketNo]) { - _menuList[_inMenu] = pocketNo; + _menuList[_inMenu] = pocketNo + 1; _inMenu++; } for (uint32 menuSlot = 0; menuSlot < _inMenu; menuSlot++) { @@ -163,11 +176,14 @@ void SwordMenu::fnStartMenu(void) { } void SwordMenu::fnEndMenu(void) { - for (uint32 cnt = 0; cnt < _inMenu; cnt++) - delete _objects[cnt]; - _screen->clearMenu(MENU_TOP); - _objectBarShown = false; - _mouse->setMenuStatus(0); + if (_objectBarShown) { + for (uint32 cnt = 0; cnt < _inMenu; cnt++) + delete _objects[cnt]; + _screen->clearMenu(MENU_TOP); + _screen->clearMenu(MENU_BOT); + _objectBarShown = false; + _mouse->setMenuStatus(0); + } } void SwordMenu::fnChooser(BsObject *compact) { @@ -191,12 +207,20 @@ void SwordMenu::fnEndChooser(void) { _subjectBarShown = false; } +void SwordMenu::checkTopMenu(void) { + if (_objectBarShown) + checkMenuClick(MENU_TOP); +} + int SwordMenu::logicChooser(BsObject *compact) { + if (_objectBarShown) + uint8 objSelected = checkMenuClick(MENU_TOP); if (checkMenuClick(MENU_BOT)) { compact->o_logic = LOGIC_script; return 1; } else return 0; + return 0; } void SwordMenu::fnAddSubject(int32 sub) { diff --git a/sword1/menu.h b/sword1/menu.h index 7ee1e04cbc..7bb5e8e355 100644 --- a/sword1/menu.h +++ b/sword1/menu.h @@ -71,6 +71,7 @@ public: void refresh(uint8 menuType); void fnStartMenu(void); void fnEndMenu(void); + void checkTopMenu(void); private: void buildSubjects(void); diff --git a/sword1/mouse.cpp b/sword1/mouse.cpp index 311dd562e6..6b243bd5b8 100644 --- a/sword1/mouse.cpp +++ b/sword1/mouse.cpp @@ -29,6 +29,7 @@ #include "sworddefs.h" #include "system.h" #include "swordres.h" +#include "menu.h" SwordMouse::SwordMouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { _resMan = pResMan; @@ -38,6 +39,7 @@ SwordMouse::SwordMouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { _menuStatus = _mouseStatus = 0; // mouse off and unlocked _getOff = 0; _specialPtrId = 0; + _inTopMenu = false; for (uint8 cnt = 0; cnt < 17; cnt++) _pointers[cnt] = (MousePtr*)_resMan->mouseResOpen(MSE_POINTER + cnt); @@ -61,8 +63,9 @@ SwordMouse::SwordMouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { // luggage & chess stuff is opened dynamically } -void SwordMouse::useLogic(SwordLogic *pLogic) { +void SwordMouse::useLogicAndMenu(SwordLogic *pLogic, SwordMenu *pMenu) { _logic = pLogic; + _menu = pMenu; } void SwordMouse::setMenuStatus(uint8 status) { @@ -107,7 +110,17 @@ void SwordMouse::engine(uint16 x, uint16 y, uint16 eventFlags) { _numObjs = 0; return; // no human, so we don't want the mouse engine } - // todo: check menus here. + + if (y < 40) { // okay, we are in the top menu. + if (!_inTopMenu) // are we just entering it? + _menu->fnStartMenu(); + _menu->checkTopMenu(); + _inTopMenu = true; + } else if (_inTopMenu) { // we're not in the menu. did we just leave it? + _menu->fnEndMenu(); + _inTopMenu = false; + } + SwordLogic::_scriptVars[MOUSE_X] = SwordLogic::_scriptVars[SCROLL_OFFSET_X] + x + 128; SwordLogic::_scriptVars[MOUSE_Y] = SwordLogic::_scriptVars[SCROLL_OFFSET_Y] + y + 128 - 40; diff --git a/sword1/mouse.h b/sword1/mouse.h index c2d872fd3e..1a433b009c 100644 --- a/sword1/mouse.h +++ b/sword1/mouse.h @@ -59,6 +59,7 @@ struct MousePtr { #endif class SwordLogic; +class SwordMenu; class ResMan; class ObjectMan; class OSystem; @@ -67,7 +68,7 @@ class SwordMouse { public: SwordMouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan); void addToList(int id, BsObject *compact); - void useLogic(SwordLogic *pLogic); + void useLogicAndMenu(SwordLogic *pLogic, SwordMenu *pMenu); void setLuggage(uint32 resID, uint32 rate); void setPointer(uint32 resID, uint32 rate); void animate(void); @@ -87,6 +88,7 @@ private: uint32 _currentPtrId, _rate, _rateCnt, _frame; OSystem *_system; SwordLogic *_logic; + SwordMenu *_menu; MouseObj _objList[MAX_MOUSE]; ResMan *_resMan; ObjectMan *_objMan; @@ -99,6 +101,7 @@ private: uint8 _menuStatus; uint32 _specialPtrId; // for special mouse cursors which aren't in the _pointers[] array. MousePtr *_specialPtr; + bool _inTopMenu; }; #endif //BSMOUSE_H diff --git a/sword1/sound.cpp b/sword1/sound.cpp index c42c6dee22..d1f9dabb72 100644 --- a/sword1/sound.cpp +++ b/sword1/sound.cpp @@ -43,8 +43,10 @@ int SwordSound::addToQueue(int32 fxNo) { if (_fxQueue[cnt].id == (uint32)fxNo) alreadyInQueue = true; if (!alreadyInQueue) { - if (_endOfQueue == MAX_FXQ_LENGTH) - error("Sound queue overflow"); + if (_endOfQueue == MAX_FXQ_LENGTH) { + warning("Sound queue overflow"); + return 0; + } _resMan->resOpen(_fxList[fxNo].sampleId); _fxQueue[_endOfQueue].id = fxNo; if (_fxList[fxNo].type == FX_SPOT) @@ -77,7 +79,7 @@ void SwordSound::engine(void) { playSample(_fxQueue[cnt]); } else { if (!_fxQueue[cnt].handle) { // sound finished - _resMan->resClose(_fxQueue[cnt].id); + _resMan->resClose(_fxList[_fxQueue[cnt].id].sampleId); if (cnt != _endOfQueue-1) _fxQueue[cnt] = _fxQueue[_endOfQueue - 1]; _endOfQueue--; @@ -86,6 +88,21 @@ void SwordSound::engine(void) { } } +void SwordSound::fnStopFx(int32 fxNo) { + + _mixer->stopID(fxNo); + for (uint8 cnt = 0; cnt < _endOfQueue; cnt++) + if (_fxQueue[cnt].id == (uint32)fxNo) { + if (!_fxQueue[cnt].delay) // sound was started + _resMan->resClose(_fxList[_fxQueue[cnt].id].sampleId); + if (cnt != _endOfQueue-1) + _fxQueue[cnt] = _fxQueue[_endOfQueue-1]; + _endOfQueue--; + return ; + } + debug(8, "fnStopFx: id not found in queue"); +} + bool SwordSound::amISpeaking(void) { return true; } @@ -98,18 +115,17 @@ void SwordSound::closeCowSysten(void) { warning("stub: SwordSound::closeCowSystem()"); } -void SwordSound::fnStopFx(int32 fxNo) { - warning("stub: SwordSound::fnStopFx(%d)", fxNo); -} - bool SwordSound::speechFinished(void) { //warning("stub: SwordSound::speechFinished()"); //return true; return (_speechHandle == 0); } -void SwordSound::startFxForScreen(uint16 screen) { // do we need this? - warning("stub: SwordSound::startFxForScreen(%d)", screen); +void SwordSound::newScreen(uint16 screen) { + // stop all running SFX + while (_endOfQueue) + fnStopFx(_fxQueue[0].id); + // I don't think that we even have to start SFX here. } void SwordSound::playSample(QueueElement elem) { diff --git a/sword1/sound.h b/sword1/sound.h index 4d17863021..a4a43ae6e8 100644 --- a/sword1/sound.h +++ b/sword1/sound.h @@ -39,7 +39,6 @@ struct QueueElement { uint32 id, delay; PlayingSoundHandle handle; - uint16 *data; // FIXME: This is a hack, because our mixer only supports Big endian data (currently) }; struct RoomVol { @@ -58,7 +57,7 @@ class SwordSound { public: SwordSound(const char *searchPath, SoundMixer *mixer, ResMan *pResMan); ~SwordSound(void); - void startFxForScreen(uint16 screen); + void newScreen(uint16 screen); bool startSpeech(uint16 roomNo, uint16 localNo); // this should work more or less. // Maybe we'll need a delay of 3 gameCycles. diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 56ee0e0ff9..4372b7cae4 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -110,7 +110,7 @@ void SwordEngine::initialize(void) { _sound = new SwordSound("", _mixer, _resMan); _menu = new SwordMenu(_screen, _mouse); _logic = new SwordLogic(_objectMan, _resMan, _screen, _mouse, _sound, _music, _menu); - _mouse->useLogic(_logic); + _mouse->useLogicAndMenu(_logic, _menu); _systemVars.justRestoredGame = _systemVars.currentCD = _systemVars.gamePaused = _systemVars.saveGameFlag = @@ -171,6 +171,7 @@ void SwordEngine::mainLoop(void) { do { // do we need the section45-hack from sword.c here? // todo: ensure right cd is inserted + _sound->newScreen(SwordLogic::_scriptVars[NEW_SCREEN]); _screen->newScreen(SwordLogic::_scriptVars[NEW_SCREEN]); _logic->newScreen(SwordLogic::_scriptVars[NEW_SCREEN]); SwordLogic::_scriptVars[SCREEN] = SwordLogic::_scriptVars[NEW_SCREEN]; @@ -221,7 +222,8 @@ void SwordEngine::mainLoop(void) { } while ((SwordLogic::_scriptVars[SCREEN] == SwordLogic::_scriptVars[NEW_SCREEN]) && (_systemVars.saveGameFlag < 2)); // change screen - if (SwordLogic::_scriptVars[SCREEN] != 53) // don't fade down after syria pan + // we don't fade down after syria pan (53). Also, scripts can call fnFadeDown, in that case, we already are fading + if ((SwordLogic::_scriptVars[SCREEN] != 53) && (!_screen->stillFading())) _screen->fadeDownPalette(); while (_screen->stillFading()) { _music->stream(); -- cgit v1.2.3