From 34d1751fe402936455fc8b57b28cb6c3eda11285 Mon Sep 17 00:00:00 2001 From: Robert Göffringmann Date: Wed, 17 Dec 2003 01:47:47 +0000 Subject: fixed resMan bug about closing of sections and started adding menu support svn-id: r11695 --- sword1/logic.cpp | 7 +- sword1/menu.cpp | 85 +++++++++--- sword1/menu.h | 21 ++- sword1/mouse.cpp | 71 ++++++---- sword1/mouse.h | 7 +- sword1/objectman.cpp | 2 +- sword1/resman.cpp | 26 +++- sword1/resman.h | 2 +- sword1/screen.cpp | 70 +++++----- sword1/screen.h | 9 +- sword1/staticres.cpp | 370 +++++++++++++++++++++++++++++++++++++++++++++++++++ sword1/sword1.cpp | 11 ++ sword1/sworddefs.h | 72 ++++++++-- sword1/text.cpp | 1 - 14 files changed, 647 insertions(+), 107 deletions(-) diff --git a/sword1/logic.cpp b/sword1/logic.cpp index f2c1f295be..83f7bde9e3 100644 --- a/sword1/logic.cpp +++ b/sword1/logic.cpp @@ -868,16 +868,13 @@ int SwordLogic::fnCheckFade(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, } int SwordLogic::fnSetSpritePalette(BsObject *cpt, int32 id, int32 spritePal, int32 d, int32 e, int32 f, int32 z, int32 x) { - _screen->fnSetPalette(184, 72, (uint8*)_resMan->openFetchRes(spritePal)); + _screen->fnSetPalette(184, 72, id, false); _resMan->resClose(spritePal); return SCRIPT_CONT; } int SwordLogic::fnSetWholePalette(BsObject *cpt, int32 id, int32 spritePal, int32 d, int32 e, int32 f, int32 z, int32 x) { - uint8 *pal = (uint8*)_resMan->openFetchRes(spritePal); - pal[0] = pal[1] = pal[2] = 0; - _screen->fnSetPalette(0, 256, pal); - _resMan->resClose(spritePal); + _screen->fnSetPalette(0, 256, id, false); return SCRIPT_CONT; } diff --git a/sword1/menu.cpp b/sword1/menu.cpp index cc7ec95f01..f7249c7fc0 100644 --- a/sword1/menu.cpp +++ b/sword1/menu.cpp @@ -39,7 +39,10 @@ SwordMenuIcon::SwordMenuIcon(uint8 menuType, uint8 menuPos, uint32 resId, uint32 } bool SwordMenuIcon::wasClicked(uint16 mouseX, uint16 mouseY) { - return false; + if ((mouseY > 440) && (mouseX >= _menuPos * 40) && (mouseX < (_menuPos + 1) * 40)) + return true; + else + return false; } void SwordMenuIcon::setSelect(bool pSel) { @@ -55,8 +58,13 @@ void SwordMenuIcon::draw(void) { SwordMenu::SwordMenu(SwordScreen *pScreen, SwordMouse *pMouse) { _screen = pScreen; _mouse = pMouse; - for (uint8 cnt = 0; cnt < 16; cnt++) + _subjectBarShown = false; + _objectBarShown = false; + for (uint8 cnt = 0; cnt < TOTAL_subjects; cnt++) _subjects[cnt] = NULL; + for (uint8 cnt = 0; cnt < TOTAL_pockets; cnt++) + _objects[cnt] = NULL; + _inMenu = 0; } uint8 SwordMenu::checkMenuClick(uint8 menuType) { @@ -68,11 +76,11 @@ uint8 SwordMenu::checkMenuClick(uint8 menuType) { if (menuType == MENU_BOT) { for (uint8 cnt = 0; cnt < SwordLogic::_scriptVars[IN_SUBJECT]; cnt++) if (_subjects[cnt]->wasClicked(x, y)) - if (mouseEvent == BS1L_BUTTON_DOWN) { + if (mouseEvent & BS1L_BUTTON_DOWN) { SwordLogic::_scriptVars[OBJECT_HELD] = _subjectBar[cnt]; buildSubjects(); return 0; - } else if (mouseEvent == BS1L_BUTTON_UP) { + } else if (mouseEvent & BS1L_BUTTON_UP) { if (SwordLogic::_scriptVars[OBJECT_HELD] == _subjectBar[cnt]) return cnt + 1; else { @@ -88,8 +96,7 @@ uint8 SwordMenu::checkMenuClick(uint8 menuType) { } void SwordMenu::buildSubjects(void) { - // uint8 subDest = 0; - clearMenu(MENU_BOT); + _screen->clearMenu(MENU_BOT); for (uint8 cnt = 0; cnt < 16; cnt++) if (_subjects[cnt]) { delete _subjects[cnt]; @@ -99,44 +106,89 @@ void SwordMenu::buildSubjects(void) { uint32 res = _subjectList[(_subjectBar[cnt] & 65535) - BASE_SUBJECT].subjectRes; uint32 frame = _subjectList[(_subjectBar[cnt] & 65535) - BASE_SUBJECT].frameNo; _subjects[cnt] = new SwordMenuIcon(MENU_BOT, cnt, res, frame, _screen); - _subjects[cnt]->setSelect(SwordLogic::_scriptVars[OBJECT_HELD] == (_subjectBar[cnt]&0xFFFF)); + _subjects[cnt]->setSelect(SwordLogic::_scriptVars[OBJECT_HELD] == _subjectBar[cnt]); _subjects[cnt]->draw(); } - //_system->update_screen(); } void SwordMenu::refresh(uint8 menuType) { //warning("stub: SwordMenu::refresh())"); } -void SwordMenu::clearMenu(uint8 menuType) { - warning("stub: SwordMenu::clearMenu()"); +void SwordMenu::buildMenu(void) { + uint32 *pockets = SwordLogic::_scriptVars + POCKET_1; + _inMenu = 0; + for (uint32 pocketNo = 0; pocketNo < TOTAL_pockets; pocketNo++) + if (pockets[pocketNo]) { + _menuList[_inMenu] = pocketNo; + _inMenu++; + } + for (uint32 menuSlot = 0; menuSlot < _inMenu; menuSlot++) { + _objects[menuSlot] = new SwordMenuIcon(MENU_TOP, menuSlot, _objectDefs[_menuList[menuSlot]].bigIconRes, _objectDefs[_menuList[menuSlot]].bigIconFrame, _screen); + uint32 objHeld = SwordLogic::_scriptVars[OBJECT_HELD]; + + // check highlighting + if (SwordLogic::_scriptVars[MENU_LOOKING] || _subjectBarShown) { // either we're in the chooser or we're doing a 'LOOK AT' + if ((!objHeld) || (objHeld == _menuList[menuSlot])) + _objects[menuSlot]->setSelect(true); + } else if (_secondItem) { // clicked luggage onto 2nd icon - we need to colour-highlight the 2 relevant icons & grey out the rest + if ((_menuList[menuSlot] == objHeld) || (_menuList[menuSlot] == _secondItem)) + _objects[menuSlot]->setSelect(true); + } else { // this object is selected - ie. GREYED OUT + if (objHeld != _menuList[menuSlot]) + _objects[menuSlot]->setSelect(true); + } + } +} + +void SwordMenu::showMenu(uint8 menuType) { + if (menuType == MENU_TOP) { + for (uint8 cnt = 0; cnt < _inMenu; cnt++) + _objects[cnt]->draw(); + } } void SwordMenu::fnStartMenu(void) { - warning("stub: SwordMenu::fnStartMenu()"); + SwordLogic::_scriptVars[OBJECT_HELD] = 0; // icon no longer selected + SwordLogic::_scriptVars[MENU_LOOKING] = 0; // second icon no longer selected (after using one on another) + _secondItem = 0; // no longer 'looking at' an icon + buildMenu(); + if (_inMenu > 0) { // if there's something in the object menu + _objectBarShown = true; + showMenu(MENU_TOP); + } else { + _objectBarShown = false; + _inMenu = 0; + } } void SwordMenu::fnEndMenu(void) { - warning("stub: SwordMenu::clearMenu()"); + for (uint32 cnt = 0; cnt < _inMenu; cnt++) + delete _objects[cnt]; + _screen->clearMenu(MENU_TOP); + _objectBarShown = false; + _mouse->setMenuStatus(0); } void SwordMenu::fnChooser(BsObject *compact) { SwordLogic::_scriptVars[OBJECT_HELD] = 0; buildSubjects(); compact->o_logic = LOGIC_choose; + _mouse->setMenuStatus(1); // so the mouse cursor will be shown. + _subjectBarShown = true; } void SwordMenu::fnEndChooser(void) { SwordLogic::_scriptVars[OBJECT_HELD] = 0; - clearMenu(MENU_BOT); - clearMenu(MENU_TOP); - //_system->update_screen(); + _screen->clearMenu(MENU_BOT); + _screen->clearMenu(MENU_TOP); for (uint8 cnt = 0; cnt < 16; cnt++) if (_subjects[cnt]) { delete _subjects[cnt]; _subjects[cnt] = NULL; } + _mouse->setMenuStatus(0); + _subjectBarShown = false; } int SwordMenu::logicChooser(BsObject *compact) { @@ -153,6 +205,5 @@ void SwordMenu::fnAddSubject(int32 sub) { } void SwordMenu::cfnReleaseMenu(void) { - clearMenu(MENU_TOP); - //_system->update_screen(); + _screen->clearMenu(MENU_TOP); } diff --git a/sword1/menu.h b/sword1/menu.h index e17a8a7d38..7ee1e04cbc 100644 --- a/sword1/menu.h +++ b/sword1/menu.h @@ -37,6 +37,14 @@ struct Subject { uint32 frameNo; }; +struct MenuObject { + int32 textDesc; + uint32 bigIconRes; + uint32 bigIconFrame; + uint32 luggageIconRes; + uint32 useScript; +}; + class SwordMenuIcon { public: SwordMenuIcon(uint8 menuType, uint8 menuPos, uint32 resId, uint32 frame, SwordScreen *screen); @@ -66,15 +74,24 @@ public: private: void buildSubjects(void); - void clearMenu(uint8 menuType); + void buildMenu(void); + void showMenu(uint8 menuType); + bool _subjectBarShown; // originally "subject_status" + bool _objectBarShown; // originally "menu_status" uint8 checkMenuClick(uint8 menuType); + //- lower menu, speech subjects: SwordMenuIcon *_subjects[16]; uint32 _subjectBar[16]; + //- top menu, items + SwordMenuIcon *_objects[TOTAL_pockets]; + uint32 _menuList[TOTAL_pockets]; + uint32 _inMenu; + uint32 _secondItem; SwordScreen *_screen; SwordMouse *_mouse; static const Subject _subjectList[TOTAL_subjects]; - + static const MenuObject _objectDefs[TOTAL_pockets + 1]; }; #endif //BSMENU_H diff --git a/sword1/mouse.cpp b/sword1/mouse.cpp index bb4896bc0a..311dd562e6 100644 --- a/sword1/mouse.cpp +++ b/sword1/mouse.cpp @@ -35,18 +35,12 @@ SwordMouse::SwordMouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { _objMan = pObjMan; _system = system; _numObjs = 0; - _mouseStatus = 0; // mouse off and unlocked + _menuStatus = _mouseStatus = 0; // mouse off and unlocked _getOff = 0; + _specialPtrId = 0; - for (uint8 cnt = 0; cnt < 17; cnt++) { - _pointers[cnt] = (MousePtr*)_resMan->openFetchRes(MSE_POINTER + cnt); -#ifdef SCUMM_BIG_ENDIAN - uint16 *data = (uint16*)_pointers[cnt]; - for (uint8 endCnt = 0; endCnt < 5; endCnt++) - data[endCnt] = READ_LE_UINT16(data + endCnt); -#endif - fixTransparency(_pointers[cnt]->data + 0x30, _pointers[cnt]->sizeX * _pointers[cnt]->sizeY * _pointers[cnt]->numFrames); - } + for (uint8 cnt = 0; cnt < 17; cnt++) + _pointers[cnt] = (MousePtr*)_resMan->mouseResOpen(MSE_POINTER + cnt); /*_resMan->resOpen(MSE_POINTER); // normal mouse (1 frame anim) _resMan->resOpen(MSE_OPERATE); _resMan->resOpen(MSE_PICKUP); @@ -71,6 +65,10 @@ void SwordMouse::useLogic(SwordLogic *pLogic) { _logic = pLogic; } +void SwordMouse::setMenuStatus(uint8 status) { + _menuStatus = status; +} + void SwordMouse::addToList(int id, BsObject *compact) { _objList[_numObjs].id = id; _objList[_numObjs].compact = compact; @@ -82,13 +80,22 @@ void SwordMouse::flushEvents(void) { } void SwordMouse::engine(uint16 x, uint16 y, uint16 eventFlags) { - //warning("Stub: SwordMouse::engine"); _state = 0; // all mouse events are flushed after one cycle. if (_lastState) { // delay all events by one cycle to notice L_button + R_button clicks correctly. _state = _lastState | eventFlags; _lastState = 0; } else if (eventFlags) _lastState = eventFlags; + + // if we received both, mouse down and mouse up event in this cycle, resort them so that + // we'll receive the up event in the next one. + if ((_state & MOUSE_DOWN_MASK) && (_state & MOUSE_UP_MASK)) { + _lastState = _state & MOUSE_UP_MASK; + _state &= MOUSE_DOWN_MASK; + } + + _mouseX = x; + _mouseY = y; if (!(_mouseStatus & 1)) { // no human? // if the mouse is turned off, I want the menu automatically removed, // except while in conversation, while examining a menu object or while combining two menu objects! @@ -122,14 +129,11 @@ void SwordMouse::engine(uint16 x, uint16 y, uint16 eventFlags) { } if (touchedId != (int)SwordLogic::_scriptVars[SPECIAL_ITEM]) { //the mouse collision situation has changed in one way or another SwordLogic::_scriptVars[SPECIAL_ITEM] = touchedId; - debug(9, "New special item: %X\n", touchedId); if (_getOff) { // there was something else selected before, run its get-off script _logic->runMouseScript(NULL, _getOff); _getOff = 0; } if (touchedId) { // there's something new selected, now. - // BsObject *compact = _objMan->fetchObject(SwordLogic::_scriptVars[SPECIAL_ITEM]); - if (_objList[clicked].compact->o_mouse_on) //run its get on _logic->runMouseScript(_objList[clicked].compact, _objList[clicked].compact->o_mouse_on); @@ -138,9 +142,9 @@ void SwordMouse::engine(uint16 x, uint16 y, uint16 eventFlags) { } } else SwordLogic::_scriptVars[SPECIAL_ITEM] = 0; - if (_state & (BS1L_BUTTON_DOWN | BS1R_BUTTON_DOWN)) { - // todo: handle menus - SwordLogic::_scriptVars[MOUSE_BUTTON] = _state; + if (_state & MOUSE_DOWN_MASK) { + // todo: handle top menu? + SwordLogic::_scriptVars[MOUSE_BUTTON] = _state & MOUSE_DOWN_MASK; if (SwordLogic::_scriptVars[SPECIAL_ITEM]) { BsObject *compact = _objMan->fetchObject(SwordLogic::_scriptVars[SPECIAL_ITEM]); _logic->runMouseScript(compact, compact->o_mouse_click); @@ -158,27 +162,44 @@ void SwordMouse::setLuggage(uint32 resId, uint32 rate) { } void SwordMouse::setPointer(uint32 resId, uint32 rate) { - _currentPtrId = resId - MSE_POINTER; + if (_specialPtrId) { + _resMan->resClose(_specialPtrId); + _specialPtrId = 0; + } _rate = rate; _rateCnt = 1; _frame = 0; + if (resId == 0) { + _rateCnt = 0; _system->set_mouse_cursor(NULL, 0, 0, 0, 0); _system->show_mouse(false); } else { + if (resId <= MSE_ARROW9) + _currentPtrId = resId - MSE_POINTER; + else { + _currentPtrId = 0; + _specialPtrId = resId; + _specialPtr = (MousePtr*)_resMan->mouseResOpen(resId); + } animate(); _system->show_mouse(true); } } void SwordMouse::animate(void) { - if (_rateCnt && (_mouseStatus == 1)) { + MousePtr *currentPtr; + if (_rateCnt && ((_mouseStatus == 1) || _menuStatus)) { + if (_specialPtrId) + currentPtr = _specialPtr; + else + currentPtr = _pointers[_currentPtrId]; _rateCnt--; if (!_rateCnt) { _rateCnt = _rate; - _frame = (_frame + 1) % _pointers[_currentPtrId]->numFrames; - uint16 size = _pointers[_currentPtrId]->sizeX * _pointers[_currentPtrId]->sizeY; - _system->set_mouse_cursor(_pointers[_currentPtrId]->data + 0x30 + _frame * size, _pointers[_currentPtrId]->sizeX, _pointers[_currentPtrId]->sizeY, _pointers[_currentPtrId]->hotSpotX, _pointers[_currentPtrId]->hotSpotY); + _frame = (_frame + 1) % currentPtr->numFrames; + uint16 size = currentPtr->sizeX * currentPtr->sizeY; + _system->set_mouse_cursor(currentPtr->data + 0x30 + _frame * size, currentPtr->sizeX, currentPtr->sizeY, currentPtr->hotSpotX, currentPtr->hotSpotY); } } } @@ -223,9 +244,3 @@ void SwordMouse::giveCoords(uint16 *x, uint16 *y) { *x = _mouseX; *y = _mouseY; } - -void SwordMouse::fixTransparency(uint8 *data, uint32 size) { - for (uint32 cnt = 0; cnt < size; cnt++) - if (data[cnt] == 0) - data[cnt] = 255; -} diff --git a/sword1/mouse.h b/sword1/mouse.h index a37b9ef0db..c2d872fd3e 100644 --- a/sword1/mouse.h +++ b/sword1/mouse.h @@ -33,6 +33,8 @@ #define BS1R_BUTTON_DOWN 8 #define BS1R_BUTTON_UP 16 #define MOUSE_BOTH_BUTTONS (BS1L_BUTTON_DOWN | BS1R_BUTTON_DOWN) +#define MOUSE_DOWN_MASK (BS1L_BUTTON_DOWN | BS1R_BUTTON_DOWN) +#define MOUSE_UP_MASK (BS1L_BUTTON_UP | BS1R_BUTTON_UP) struct MouseObj { int id; @@ -79,8 +81,8 @@ public: void fnNormalMouse(void); void fnLockMouse(void); void fnUnlockMouse(void); + void setMenuStatus(uint8 status); private: - void fixTransparency(uint8 *data, uint32 size); MousePtr *_pointers[17]; uint32 _currentPtrId, _rate, _rateCnt, _frame; OSystem *_system; @@ -94,6 +96,9 @@ private: uint16 _numObjs; uint16 _lastState, _state; uint32 _getOff; + uint8 _menuStatus; + uint32 _specialPtrId; // for special mouse cursors which aren't in the _pointers[] array. + MousePtr *_specialPtr; }; #endif //BSMOUSE_H diff --git a/sword1/objectman.cpp b/sword1/objectman.cpp index 94fa4b65dd..a2f0881c9e 100644 --- a/sword1/objectman.cpp +++ b/sword1/objectman.cpp @@ -65,7 +65,7 @@ void ObjectMan::megaLeaving(uint16 section, int id) { error("mega %d is leaving empty section %d", id, section); _liveList[section]--; if ((_liveList[section] == 0) && (id != PLAYER)) { - _resMan->resClose(_liveList[section]); + _resMan->resClose(_objectList[section]); _cptData[section] = NULL; } /* if the player is leaving the section then we have to close the resources after diff --git a/sword1/resman.cpp b/sword1/resman.cpp index 7a07747526..352950e9b8 100644 --- a/sword1/resman.cpp +++ b/sword1/resman.cpp @@ -173,14 +173,11 @@ void ResMan::resOpen(uint32 id) { // load resource ID into memory if (memHandle->cond == MEM_FREED) { // memory has been freed uint32 size = resLength(id); _memMan->alloc(memHandle, size); - // uint8 *dest = (uint8*)memHandle->data; File *clusFile = openClusterFile(id); clusFile->seek( resOffset(id) ); clusFile->read( memHandle->data, size); if (clusFile->ioFailed()) error("Can't read %d bytes from cluster %d\n", size, id); - // original loop was a lot more complicated, more error handling and - // some calls to the music system, don't think we'll need that. clusFile->close(); delete clusFile; } else @@ -211,7 +208,7 @@ FrameHeader *ResMan::fetchFrame(void *resourceData, uint32 frameNo) { } File *ResMan::openClusterFile(uint32 id) { - File *clusFile = new File();; + File *clusFile = new File(); char fullPath[MAX_PATH_LEN]; char fileName[15]; makePathToCluster(fullPath); @@ -248,6 +245,27 @@ void ResMan::makePathToCluster(char *str) { // todo: add search stuff, cd1, cd2, etc. } +void *ResMan::mouseResOpen(uint32 id) { + BsMemHandle *memHandle = resHandle(id); + if (memHandle->cond == MEM_FREED) { + resOpen(id); +#ifdef SCUMM_BIG_ENDIAN + uint16 *head = (uint16*)memHandle->data; + for (uint8 endCnt = 0; endCnt < 5; endCnt++) + head[endCnt] = READ_LE_UINT16(head + endCnt); +#endif + // fix transparency: + uint8 *rawData = (uint8*)memHandle->data; + uint32 size = READ_LE_UINT16(rawData) * READ_LE_UINT16(rawData + 2) * READ_LE_UINT16(rawData + 4); + rawData += 0x3A; + for (uint32 cnt = 0; cnt < size; cnt++) + if (rawData[cnt] == 0) + rawData[cnt] = 255; + return memHandle->data; + } else + return openFetchRes(id); +} + void ResMan::openCptResourceBigEndian(uint32 id) { resOpen(id); BsMemHandle *handle = resHandle(id); diff --git a/sword1/resman.h b/sword1/resman.h index 1e69844414..847e467d8c 100644 --- a/sword1/resman.h +++ b/sword1/resman.h @@ -51,12 +51,12 @@ public: ResMan(const char *resFile, MemMan *pMemoMan); ~ResMan(void); void resClose(uint32 id); - //void resOpen(uint32 id); void resOpen(uint32 id); void *fetchRes(uint32 id); void dumpRes(uint32 id); void *openFetchRes(uint32 id); void *cptResOpen(uint32 id); + void *mouseResOpen(uint32 id); Header *lockScript(uint32 scrID); void unlockScript(uint32 scrID); FrameHeader *fetchFrame(void *resourceData, uint32 frameNo); diff --git a/sword1/screen.cpp b/sword1/screen.cpp index 4a3c974321..bc0811258e 100644 --- a/sword1/screen.cpp +++ b/sword1/screen.cpp @@ -29,7 +29,7 @@ #include "scummsys.h" #include "common/util.h" #include "system.h" -#include "router.h" +#include "menu.h" #define SCROLL_FRACTION 16 #define MAX_SCROLL_DISTANCE 8 @@ -112,14 +112,21 @@ void SwordScreen::fadeUpPalette(void) { _fadingDirection = FADE_UP; } -void SwordScreen::fnSetPalette(uint8 start, uint16 length, uint8 *data) { - memcpy(_targetPalette + start * 3, data, length * 3); - _system->set_palette(data, start, length); -} - -void SwordScreen::fnSetFadeTargetPalette(uint8 start, uint16 length, uint8 *data) { - memcpy(_targetPalette + start * 3, data, length * 3); - debug(1, "fnSetFadeTargetPalette called"); +void SwordScreen::fnSetPalette(uint8 start, uint16 length, uint32 id, bool fadeUp) { + uint8 *palData = (uint8*)_resMan->openFetchRes(id); + if (start == 0) // force color 0 to black + palData[0] = palData[1] = palData[2] = 0; + for (uint32 cnt = 0; cnt < length; cnt++) { + _targetPalette[(start + cnt) * 4 + 0] = palData[cnt * 3 + 0] << 2; + _targetPalette[(start + cnt) * 4 + 1] = palData[cnt * 3 + 1] << 2; + _targetPalette[(start + cnt) * 4 + 2] = palData[cnt * 3 + 2] << 2; + } + _resMan->resClose(id); + if (fadeUp) { + _fadingStep = 1; + _fadingDirection = 1; + } else + _system->set_palette(_targetPalette, start, length); } bool SwordScreen::stillFading(void) { @@ -255,7 +262,7 @@ void SwordScreen::newScreen(uint32 screen) { _screenGrid = (uint8*)malloc(_gridSizeX * _gridSizeY); memset(_screenGrid, 0x80, _gridSizeX * _gridSizeY); // force refresh for (uint8 cnt = 0; cnt < _roomDefTable[_currentScreen].totalLayers; cnt++) { - // open and lock all resources, will be closed in closeScreen() + // open and lock all resources, will be closed in quitScreen() _layerBlocks[cnt] = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].layers[cnt]); if (cnt > 0) _layerBlocks[cnt] += sizeof(Header); @@ -271,23 +278,8 @@ void SwordScreen::newScreen(uint32 screen) { if (_roomDefTable[_currentScreen].parallax[1]) _parallax[1] = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].parallax[1]); - // TEMPORARY! - uint8 *bgPal = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].palettes[0]); - // uint8 *sprPal = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].palettes[1]); - for (uint16 cnt = 0; cnt < 256; cnt++) { - _targetPalette[cnt * 4 + 0] = bgPal[cnt * 3 + 0] << 2; - _targetPalette[cnt * 4 + 1] = bgPal[cnt * 3 + 1] << 2; - _targetPalette[cnt * 4 + 2] = bgPal[cnt * 3 + 2] << 2; - } - /*for (uint16 cnt = 0; cnt < 72; cnt++) { - _targetPalette[(cnt + 184) * 4 + 0] = bgPal[cnt * 3 + 0]; - _targetPalette[(cnt + 184) * 4 + 1] = bgPal[cnt * 3 + 1]; - _targetPalette[(cnt + 184) * 4 + 2] = bgPal[cnt * 3 + 2]; - }*/ - _targetPalette[0] = _targetPalette[1] = _targetPalette[2] = 0; - _system->set_palette(_targetPalette, 0, 256); - _resMan->resClose(_roomDefTable[_currentScreen].palettes[0]); - //_resMan->resClose(_roomDefTable[_currentScreen].palettes[1]); + fnSetPalette(0, 184, _roomDefTable[_currentScreen].palettes[0], true); + fnSetPalette(184, 72, _roomDefTable[_currentScreen].palettes[1], true); } void SwordScreen::quitScreen(void) { @@ -731,14 +723,30 @@ void SwordScreen::spriteClipAndSet(uint16 *pSprX, uint16 *pSprY, uint16 *pSprWid } } -void SwordScreen::showFrame(uint16 x, uint16 y, uint32 resId, uint32 frameNo) { - warning("stub: SwordScreen::showFrame(%d, %d, %d, %d)", x, y, resId, frameNo); -} - void SwordScreen::fnFlash(uint8 color) { warning("stub: SwordScreen::fnFlash(%d)", color); } +// ------------------- SwordMenu screen interface --------------------------- + +void SwordScreen::showFrame(uint16 x, uint16 y, uint32 resId, uint32 frameNo) { + FrameHeader *frameHead = _resMan->fetchFrame(_resMan->openFetchRes(resId), frameNo); + uint8 *frameData = ((uint8*)frameHead) + sizeof(FrameHeader); + _system->copy_rect(frameData, FROM_LE_16(frameHead->width), x, y, FROM_LE_16(frameHead->width), FROM_LE_16(frameHead->height)); + _resMan->resClose(resId); +} + +void SwordScreen::clearMenu(uint8 menuType) { + // isn't there a better way to do this? + uint8 *tmp = (uint8*)malloc(640 * 40); + memset(tmp, 0, 640 * 40); + if (menuType == MENU_BOT) + _system->copy_rect(tmp, 640, 0, 440, 640, 40); + else + _system->copy_rect(tmp, 640, 0, 0, 640, 40); + free(tmp); +} + // ------------------- router debugging code -------------------------------- void SwordScreen::vline(uint16 x, uint16 y1, uint16 y2) { diff --git a/sword1/screen.h b/sword1/screen.h index 943087bacf..1b3cee8b75 100644 --- a/sword1/screen.h +++ b/sword1/screen.h @@ -59,7 +59,6 @@ class ResMan; class ObjectMan; class SwordText; // Text objects use sprites that are created internally at run-time // the buffer belongs to SwordText, so we need a reference here. -class SwordRouter; class OSystem; class SwordScreen { @@ -77,16 +76,16 @@ public: void addToGraphicList(uint8 listId, uint32 objId); void recreate(); - void spritesAndParallax(void); //=> background_parallax, backsprites, sortsprites - // foreground_parallax, foresprites + void spritesAndParallax(void); + void fadeDownPalette(void); void fadeUpPalette(void); - void fnSetPalette(uint8 start, uint16 length, uint8 *data); - void fnSetFadeTargetPalette(uint8 start, uint16 length, uint8 *data); + void fnSetPalette(uint8 start, uint16 length, uint32 id, bool fadeUp); bool stillFading(void); void updateScreen(void); void showFrame(uint16 x, uint16 y, uint32 resId, uint32 frameNo); + void clearMenu(uint8 menuType); void fnSetParallax(uint32 screen, uint32 resId); void fnFlash(uint8 color); diff --git a/sword1/staticres.cpp b/sword1/staticres.cpp index 398cecd394..a7169eb556 100644 --- a/sword1/staticres.cpp +++ b/sword1/staticres.cpp @@ -28,6 +28,376 @@ #include "music.h" #include "sound.h" +const MenuObject SwordMenu::_objectDefs[TOTAL_pockets + 1] = { + { // 0 can't use + 0, + }, + { // 1 NEWSPAPER + menu_newspaper, // text_desc + ICON_NEWSPAPER, // big_icon_res + 0, // big_icon_frame + LUGG_NEWSPAPER, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 2 HAZEL_WAND + menu_hazel_wand, // text_desc + ICON_HAZEL_WAND, // big_icon_res + 0, // big_icon_frame + LUGG_HAZEL_WAND, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 3 BEER_TOWEL + 0, // text_desc - SEE MENU.SCR + ICON_BEER_TOWEL, // big_icon_res + 0, // big_icon_frame + LUGG_BEER_TOWEL, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 4 HOTEL_KEY + menu_hotel_key, // text_desc + ICON_HOTEL_KEY, // big_icon_res + 0, // big_icon_frame + LUGG_HOTEL_KEY, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 5 BALL + menu_ball, // text_desc + ICON_BALL, // big_icon_res + 0, // big_icon_frame + LUGG_BALL, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 6 STATUETTE + menu_statuette, // text_desc + ICON_STATUETTE, // big_icon_res + 0, // big_icon_frame + LUGG_STATUETTE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 7 RED_NOSE + 0, // text_desc - SEE MENU.SCR + ICON_RED_NOSE, // big_icon_res + 0, // big_icon_frame + LUGG_RED_NOSE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 8 POLISHED_CHALICE + menu_polished_chalice, // text_desc + ICON_POLISHED_CHALICE, // big_icon_res + 0, // big_icon_frame + LUGG_POLISHED_CHALICE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 9 DOLLAR_BILL + menu_dollar_bill, // text_desc + ICON_DOLLAR_BILL, // big_icon_res + 0, // big_icon_frame + LUGG_DOLLAR_BILL, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 10 PHOTO + menu_photograph, // text_desc + ICON_PHOTOGRAPH, // big_icon_res + 0, // big_icon_frame + LUGG_PHOTOGRAPH, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 11 FLASHLIGHT + menu_flashlight, // text_desc + ICON_FLASHLIGHT, // big_icon_res + 0, // big_icon_frame + LUGG_FLASHLIGHT, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 12 FUSE_WIRE + menu_fuse_wire, // text_desc + ICON_FUSE_WIRE, // big_icon_res + 0, // big_icon_frame + LUGG_FUSE_WIRE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 13 GEM + menu_gem, // text_desc + ICON_GEM, // big_icon_res + 0, // big_icon_frame + LUGG_GEM, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 14 STATUETTE_PAINT + menu_statuette_paint, // text_desc + ICON_STATUETTE_PAINT, // big_icon_res + 0, // big_icon_frame + LUGG_STATUETTE_PAINT, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 15 STICK + menu_stick, // text_desc + ICON_STICK, // big_icon_res + 0, // big_icon_frame + LUGG_STICK, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 16 EXCAV_KEY + menu_excav_key, // text_desc + ICON_EXCAV_KEY, // big_icon_res + 0, // big_icon_frame + LUGG_EXCAV_KEY, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 17 LAB_PASS + menu_lab_pass, // text_desc + ICON_LAB_PASS, // big_icon_res + 0, // big_icon_frame + LUGG_LAB_PASS, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 18 LIFTING_KEYS + menu_lifting_keys, // text_desc + ICON_LIFTING_KEYS, // big_icon_res + 0, // big_icon_frame + LUGG_LIFTING_KEYS, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 19 MANUSCRIPT + menu_manuscript, // text_desc + ICON_MANUSCRIPT, // big_icon_res + 0, // big_icon_frame + LUGG_MANUSCRIPT, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 20 MATCH_BOOK + menu_match_book, // text_desc + ICON_MATCHBOOK, // big_icon_res + 0, // big_icon_frame + LUGG_MATCHBOOK, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 21 SUIT_MATERIAL + menu_suit_material, // text_desc + ICON_SUIT_MATERIAL, // big_icon_res + 0, // big_icon_frame + LUGG_SUIT_MATERIAL, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 22 STICK_TOWEL + menu_stick_towel, // text_desc + ICON_STICK_TOWEL, // big_icon_res + 0, // big_icon_frame + LUGG_STICK_TOWEL, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 23 PLASTER + menu_plaster, // text_desc + ICON_PLASTER, // big_icon_res + 0, // big_icon_frame + LUGG_PLASTER, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 24 PRESSURE_GAUGE + menu_pressure_gauge, // text_desc + ICON_PRESSURE_GAUGE, // big_icon_res + 0, // big_icon_frame + LUGG_PRESSURE_GAUGE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 25 RAILWAY_TICKET + menu_railway_ticket, // text_desc + ICON_RAILWAY_TICKET, // big_icon_res + 0, // big_icon_frame + LUGG_RAILWAY_TICKET, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 26 BUZZER + menu_buzzer, // text_desc + ICON_BUZZER, // big_icon_res + 0, // big_icon_frame + LUGG_BUZZER, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 27 ROSSO_CARD + menu_rosso_card, // text_desc + ICON_ROSSO_CARD, // big_icon_res + 0, // big_icon_frame + LUGG_ROSSO_CARD, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 28 TOILET_KEY + menu_toilet_key, // text_desc + ICON_TOILET_KEY, // big_icon_res + 0, // big_icon_frame + LUGG_TOILET_KEY, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 29 SOAP + menu_soap, // text_desc + ICON_SOAP, // big_icon_res + 0, // big_icon_frame + LUGG_SOAP, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 30 STONE_KEY + menu_stone_key, // text_desc + ICON_STONE_KEY, // big_icon_res + 0, // big_icon_frame + LUGG_STONE_KEY, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 31 CHALICE + menu_chalice, // text_desc + ICON_CHALICE, // big_icon_res + 0, // big_icon_frame + LUGG_CHALICE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 32 TISSUE + menu_tissue, // text_desc + ICON_TISSUE, // big_icon_res + 0, // big_icon_frame + LUGG_TISSUE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 33 TOILET_BRUSH + menu_toilet_brush, // text_desc + ICON_TOILET_BRUSH, // big_icon_res + 0, // big_icon_frame + LUGG_TOILET_BRUSH, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 34 TOILET_CHAIN + menu_toilet_chain, // text_desc + ICON_TOILET_CHAIN, // big_icon_res + 0, // big_icon_frame + LUGG_TOILET_CHAIN, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 35 TOWEL + menu_towel, // text_desc + ICON_TOWEL, // big_icon_res + 0, // big_icon_frame + LUGG_TOWEL, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 36 TRIPOD + menu_tripod, // text_desc + ICON_TRIPOD, // big_icon_res + 0, // big_icon_frame + LUGG_TRIPOD, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 37 LENS + menu_lens, // text_desc + ICON_LENS, // big_icon_res + 0, // big_icon_frame + LUGG_LENS, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 38 MIRROR + menu_mirror, // text_desc + ICON_MIRROR, // big_icon_res + 0, // big_icon_frame + LUGG_MIRROR, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 39 TOWEL_CUT + menu_towel_cut, // text_desc + ICON_TOWEL_CUT, // big_icon_res + 0, // big_icon_frame + LUGG_TOWEL_CUT, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 40 BIBLE + menu_bible, // text_desc + ICON_BIBLE, // big_icon_res + 0, // big_icon_frame + LUGG_BIBLE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 41 TISSUE_CHARRED + menu_tissue_charred, // text_desc + ICON_TISSUE_CHARRED, // big_icon_res + 0, // big_icon_frame + LUGG_TISSUE_CHARRED, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 42 FALSE_KEY + menu_false_key, // text_desc + ICON_FALSE_KEY, // big_icon_res + 0, // big_icon_frame + LUGG_FALSE_KEY, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 43 PAINTED_KEY - looks identical to excav key, so uses that icon & luggage + menu_painted_key, // text_desc + ICON_EXCAV_KEY, // big_icon_res + 0, // big_icon_frame + LUGG_EXCAV_KEY, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 44 KEYRING + 0, // text_desc - SEE MENU.SCR + ICON_KEYRING, // big_icon_res + 0, // big_icon_frame + LUGG_KEYRING, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 45 SOAP_IMP + menu_soap_imp, // text_desc + ICON_SOAP_IMP, // big_icon_res + 0, // big_icon_frame + LUGG_SOAP_IMP, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 46 SOAP_PLAS + menu_soap_plas, // text_desc + ICON_SOAP_PLAS, // big_icon_res + 0, // big_icon_frame + LUGG_SOAP_PLAS, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 47 COG_1 - the larger cog with spindle attached + menu_cog_1, // text_desc + ICON_COG_1, // big_icon_res + 0, // big_icon_frame + LUGG_COG_1, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 48 COG_2 - the smaller cog, found in the rubble + menu_cog_2, // text_desc + ICON_COG_2, // big_icon_res + 0, // big_icon_frame + LUGG_COG_2, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 49 HANDLE + menu_handle, // text_desc + ICON_HANDLE, // big_icon_res + 0, // big_icon_frame + LUGG_HANDLE, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 50 COIN + menu_coin, // text_desc + ICON_COIN, // big_icon_res + 0, // big_icon_frame + LUGG_COIN, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 51 BIRO + menu_biro, // text_desc + ICON_BIRO, // big_icon_res + 0, // big_icon_frame + LUGG_BIRO, // luggage_icon_res + SCR_icon_combine_script, // use_script + }, + { // 52 PIPE + menu_pipe, // text_desc + ICON_PIPE, // big_icon_res + 0, // big_icon_frame + LUGG_PIPE, // luggage_icon_res + SCR_icon_combine_script, // use_script + } +}; + const Subject SwordMenu::_subjectList[TOTAL_subjects] = { { // 256 0, // subject_res diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 9fd61c4f74..56ee0e0ff9 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -224,6 +224,7 @@ void SwordEngine::mainLoop(void) { if (SwordLogic::_scriptVars[SCREEN] != 53) // don't fade down after syria pan _screen->fadeDownPalette(); while (_screen->stillFading()) { + _music->stream(); _screen->updateScreen(); delay(1000/12); // todo: fade sfx? @@ -267,6 +268,16 @@ void SwordEngine::delay(uint amount) { //copied and mutilated from sky.cpp break; case OSystem::EVENT_RBUTTONDOWN: _mouseState |= BS1R_BUTTON_DOWN; +#ifdef _WIN32_WCE + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; +#endif + break; + case OSystem::EVENT_LBUTTONUP: + _mouseState |= BS1L_BUTTON_UP; + break; + case OSystem::EVENT_RBUTTONUP: + _mouseState |= BS1R_BUTTON_UP; break; case OSystem::EVENT_QUIT: _system->quit(); diff --git a/sword1/sworddefs.h b/sword1/sworddefs.h index 4ce19a712a..b57e9fb98c 100644 --- a/sword1/sworddefs.h +++ b/sword1/sworddefs.h @@ -48,6 +48,7 @@ #define LOGIC_new_script 15 #define LOGIC_pause_for_event 16 +#define TOTAL_pockets 52 #define TOTAL_subjects (375-256+1) #define BASE_SUBJECT 256 @@ -59,16 +60,6 @@ #define MAX_text_obs 2 //text compacts #define TEXT_sect 149 //text compacts exist in section 149, probably after all the megas -/*struct Header { - // I took this one from QEADER.H, but it looks like it's something different than _header. - // => commented out. - int16 version; - char type[4]; - int32 comp_length; - char compression[4]; - int32 decomp_length; -};*/ - #if !defined(__GNUC__) #pragma START_PACK_STRUCTS #endif @@ -149,6 +140,65 @@ enum Language { #define ALBERT 9568256 #define DUANE 8781824 +#define menu_bible 69 +#define menu_newspaper 1 +#define menu_hazel_wand 2 +#define menu_beer_towel 68 +#define menu_beer_towel_wet 4 +#define menu_beer_towel_damp 5 +#define menu_beer_towel_dried 6 +#define menu_hotel_key 7 +#define menu_ball 8 +#define menu_statuette 9 +#define menu_red_nose_first 10 +#define menu_red_nose_second 11 +#define menu_polished_chalice 12 +#define menu_dollar_bill 13 +#define menu_photograph 14 +#define menu_keyring_first 15 +#define menu_keyring_second 70 +#define menu_keyring_third 17 +#define menu_fuse_wire 18 +#define menu_gem 19 +#define menu_statuette_paint 20 +#define menu_stick 21 +#define menu_excav_key 71 +#define menu_false_key 72 +#define menu_painted_key 73 +#define menu_lab_pass 25 +#define menu_lifting_keys 26 +#define menu_manuscript 27 +#define menu_match_book 28 +#define menu_suit_material 29 +#define menu_stick_towel 30 +#define menu_plaster 31 +#define menu_pressure_gauge 32 +#define menu_railway_ticket 33 +#define menu_buzzer 74 +#define menu_rosso_card 75 +#define menu_toilet_key 36 +#define menu_soap 76 +#define menu_soap_imp 77 +#define menu_soap_plas 78 +#define menu_stone_key 79 +#define menu_chalice 41 +#define menu_tissue 42 +#define menu_toilet_brush 80 +#define menu_toilet_chain 44 +#define menu_towel 45 +#define menu_tripod 46 +#define menu_lens 81 +#define menu_towel_cut 48 +#define menu_mirror 82 +#define menu_tissue_charred 50 +#define menu_cog_1 51 +#define menu_cog_2 52 +#define menu_handle 83 +#define menu_coin 84 +#define menu_biro 55 +#define menu_pipe 56 +#define menu_flashlight 57 + #define IT_MCODE 1 // Call an mcode routine #define IT_PUSHNUMBER 2 // push a number on the stack #define IT_PUSHVARIABLE 3 // push a variable on the stack @@ -1386,6 +1436,6 @@ enum ScriptVariableNames { #define GUARD_ROOF_63 4128781 #define LEFT_TREE_POINTER_71 4653058 #define RIGHT_TREE_POINTER_71 4653059 - +#define SCR_icon_combine_script (0*0x10000 + 25) #endif //SWORDDEFS_H diff --git a/sword1/text.cpp b/sword1/text.cpp index 6b4f354e72..da920c298e 100644 --- a/sword1/text.cpp +++ b/sword1/text.cpp @@ -49,7 +49,6 @@ SwordText::SwordText(ObjectMan *pObjMan, ResMan *pResMan, bool czechVersion) { } uint32 SwordText::lowTextManager(uint8 *ascii, int32 width, uint8 pen) { - // get rid of that textId thing! _textCount++; if (_textCount > MAX_TEXT_OBS) error("SwordText::lowTextManager: MAX_TEXT_OBS exceeded!"); -- cgit v1.2.3