From bc2b9449869088be4f6c55ff03ccfa9a267a8c6a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 2 May 2012 00:23:41 +1000 Subject: TONY: Added code from Inventory.cpp --- engines/tony/font.h | 12 +- engines/tony/gfxcore.h | 28 +- engines/tony/inventory.cpp | 943 +++++++++++++++++++++++++++++++++++++++++++++ engines/tony/inventory.h | 5 +- engines/tony/module.mk | 1 + engines/tony/utils.cpp | 8 +- engines/tony/utils.h | 8 +- 7 files changed, 976 insertions(+), 29 deletions(-) create mode 100644 engines/tony/inventory.cpp (limited to 'engines') diff --git a/engines/tony/font.h b/engines/tony/font.h index 57a8b1c4fb..a8a9aabb19 100644 --- a/engines/tony/font.h +++ b/engines/tony/font.h @@ -54,9 +54,12 @@ namespace Tony { +class RMInput; class RMInventory; -class RMLoc; class RMItem; +class RMLoc; +class RMLocation; +class RMPointer; /** * Gestisce un font, in cui ha varie surface per ogni lettera @@ -237,8 +240,7 @@ public: /** * Gestisce il testo di un dialogo */ -class RMTextDialog : public RMText -{ +class RMTextDialog : public RMText { protected: int m_startTime; int m_time; @@ -250,7 +252,7 @@ class RMTextDialog : public RMText bool m_bForceNoTime; HANDLE hCustomSkip; HANDLE hCustomSkip2; - RMInput* m_input; + RMInput *m_input; bool m_bAlwaysDisplay; bool m_bNoTab; @@ -296,7 +298,7 @@ class RMTextDialog : public RMText class RMTextDialogScrolling : public RMTextDialog { protected: - RMLocation* curLoc; + RMLocation *curLoc; RMPoint startScroll; virtual void ClipOnScreen(RMGfxPrimitive* prim); diff --git a/engines/tony/gfxcore.h b/engines/tony/gfxcore.h index f5553d21c6..2e4f9830ed 100644 --- a/engines/tony/gfxcore.h +++ b/engines/tony/gfxcore.h @@ -127,37 +127,37 @@ public: m_task = task; m_bFlag = 0; } - RMGfxPrimitive(RMGfxTask *task, RMRect &src, RMRect &dst) { + RMGfxPrimitive(RMGfxTask *task, const RMRect &src, RMRect &dst) { m_task = task; m_src = src; m_dst = dst; m_bFlag = 0; m_bStretch = (src.Width() != dst.Width() || src.Height() != dst.Height()); } - RMGfxPrimitive(RMGfxTask *task, RMPoint &src, RMRect &dst) { + RMGfxPrimitive(RMGfxTask *task, const RMPoint &src, RMRect &dst) { m_task = task; m_src.TopLeft() = src; m_dst = dst; m_bFlag = 0; } - RMGfxPrimitive(RMGfxTask *task, RMPoint &src, RMPoint &dst) { + RMGfxPrimitive(RMGfxTask *task, const RMPoint &src, RMPoint &dst) { m_task = task; m_src.TopLeft() = src; m_dst.TopLeft() = dst; m_bFlag = 0; } - RMGfxPrimitive(RMGfxTask *task, RMRect &src, RMPoint &dst) { + RMGfxPrimitive(RMGfxTask *task, const RMRect &src, RMPoint &dst) { m_task = task; m_src = src; m_dst.TopLeft() = dst; m_bFlag = 0; } - RMGfxPrimitive(RMGfxTask *task, RMRect &dst) { + RMGfxPrimitive(RMGfxTask *task, const RMRect &dst) { m_task = task; m_dst = dst; m_src.SetEmpty(); m_bFlag = 0; } - RMGfxPrimitive(RMGfxTask *task, RMPoint &dst) { + RMGfxPrimitive(RMGfxTask *task, const RMPoint &dst) { m_task = task; m_dst.TopLeft() = dst; m_src.SetEmpty(); m_bFlag = 0; } void SetFlag(byte bFlag) { m_bFlag=bFlag; } void SetTask(RMGfxTask *task) { m_task = task; } - void SetSrc(RMRect &src) { m_src = src; } - void SetSrc(RMPoint &src) { m_src.TopLeft() = src; } - void SetDst(RMRect &dst) { m_dst = dst; } - void SetDst(RMPoint &dst) { m_dst.TopLeft() = dst; } + void SetSrc(const RMRect &src) { m_src = src; } + void SetSrc(const RMPoint &src) { m_src.TopLeft() = src; } + void SetDst(const RMRect &dst) { m_dst = dst; } + void SetDst(const RMPoint &dst) { m_dst.TopLeft() = dst; } void SetStrecth(bool bStretch) { m_bStretch = bStretch; } bool HaveDst() { return !m_dst.IsEmpty(); } @@ -292,7 +292,7 @@ public: virtual void Init(RMDataStream& ds, int dimx, int dimy, bool bLoadPalette = false); int LoadPaletteWA(uint32 resID, bool bSwapped = false); - int LoadPaletteWA(byte *buf, bool bSwapped = false); + int LoadPaletteWA(const byte *buf, bool bSwapped = false); int LoadPalette(uint32 resID); int LoadPalette(byte *buf); }; @@ -365,7 +365,7 @@ public: // Overload of the initialization method virtual void Init(RMDataStream& ds, int dimx, int dimy, bool bLoadPalette = false); - virtual int Init(byte *buf, int dimx, int dimy, bool bLoadPalette = false); + virtual int Init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false); // Draw image with RLE decompression void Draw(RMGfxTargetBuffer& bigBuf, RMGfxPrimitive* prim); @@ -447,8 +447,8 @@ public: void Draw(RMGfxTargetBuffer& bigBuf, RMGfxPrimitive* prim); // Overloaded initialisation methods - virtual void Init(RMDataStream& ds, int dimx, int dimy, bool bLoadPalette = false); - virtual int Init(byte *buf, int dimx, int dimy, bool bLoadPalette = false); + virtual void Init(RMDataStream &ds, int dimx, int dimy, bool bLoadPalette = false); + virtual int Init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false); virtual ~RMGfxSourceBuffer8RLEByteAA(); }; diff --git a/engines/tony/inventory.cpp b/engines/tony/inventory.cpp new file mode 100644 index 0000000000..2ce88b1cec --- /dev/null +++ b/engines/tony/inventory.cpp @@ -0,0 +1,943 @@ +/* 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. + * + */ +/************************************************************************** + * ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ * + * Nayma Software srl * + * e -= We create much MORE than ALL =- * + * u- z$$$c '. ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ * + * .d" d$$$$$b "b. * + * .z$* d$$$$$$$L ^*$c. * + * #$$$. $$$$$$$$$ .$$$" Project: Roasted Moths........ * + * ^*$b 4$$$$$$$$$F .d$*" * + * ^$$. 4$$$$$$$$$F .$P" Module: Inventory.CPP........ * + * *$. '$$$$$$$$$ 4$P 4 * + * J *$ "$$$$$$$" $P r Author: Giovanni Bajo........ * + * z$ '$$$P*4c.*$$$*.z@*R$$$ $. * + * z$" "" #$F^ "" '$c * + * z$$beu .ue=" $ "=e.. .zed$$c * + * "#$e z$*" . `. ^*Nc e$"" * + * "$$". .r" ^4. .^$$" * + * ^.@*"6L=\ebu^+C$"*b." * + * "**$. "c 4$$$ J" J$P*" OS: [ ] DOS [X] WIN95 [ ] PORT * + * ^"--.^ 9$" .--"" COMP: [ ] WATCOM [X] VISUAL C++ * + * " [ ] EIFFEL [ ] GCC/GXX/DJGPP * + * * + * This source code is Copyright (C) Nayma Software. ALL RIGHTS RESERVED * + * * + **************************************************************************/ + +#include "common/textconsole.h" +#include "tony/mpal/mpalutils.h" +#include "tony/inventory.h" +#include "tony/game.h" +#include "tony/tony.h" + +namespace Tony { + + +/****************************************************************************\ +* RMInventory Methods +\****************************************************************************/ + +RMInventory::RMInventory() { + m_items = NULL; + m_state = CLOSED; + m_bCombining = false; +} + +RMInventory::~RMInventory() { + Close(); +} + +bool RMInventory::CheckPointInside(RMPoint &pt) { + if (!bCfgInvUp) + return pt.y > RM_SY - 70; + else + return pt.y < 70; +} + + + +void RMInventory::Init(void) { + int i,j; + int curres; + + // Crea il buffer principale + Create(RM_SX, 68); + SetPriority(185); + + // Pulisce l'inventario + m_nInv = 0; + m_curPos = 0; + m_bCombining = false; + + // Nuovi oggetti + m_nItems = 78; // @@@ Numero di oggetti prendibili + m_items = new RMInventoryItem[m_nItems+1]; + + curres = 10500; + + // Loop sugli oggetti + for (i = 0; i <= m_nItems; i++) { + // Carica l'oggetto da risorsa + RMRes res(curres); + RMDataStream ds; + + assert(res.IsValid()); + + // Non deve inizializzare il cur pattern dell'oggetto dell'inventario leggendolo da MPAL! + // Glelo mettiamo noi a MANO, e non c'entra nulla con l'oggetto in MPAL + m_items[i].icon.SetInitCurPattern(false); + ds.OpenBuffer(res); + ds >> m_items[i].icon; + ds.Close(); + + // Mette di default a pattern 1 + m_items[i].status=1; + m_items[i].icon.SetPattern(1); + m_items[i].icon.DoFrame(this, false); + + curres++; + if (i == 0 || i == 28 || i == 29) continue; + + m_items[i].pointer=new RMGfxSourceBuffer8RLEByteAA[m_items[i].icon.NumPattern()]; + + for (j=0;j> miniInterface; + miniInterface.SetPattern(1); + ds.Close(); + + // Crea il testo per gli hints sulla mini interfaccia + m_hints[0].SetAlignType(RMText::HCENTER,RMText::VTOP); + m_hints[1].SetAlignType(RMText::HCENTER,RMText::VTOP); + m_hints[2].SetAlignType(RMText::HCENTER,RMText::VTOP); + + // Il testo viene preso da MPAL per la traduzione + RMMessage msg1(15); + RMMessage msg2(13); + RMMessage msg3(14); + + m_hints[0].WriteText(msg1[0],1); + m_hints[1].WriteText(msg2[0],1); + m_hints[2].WriteText(msg3[0],1); + +/* + m_hints[0].WriteText("Examine",1); + m_hints[1].WriteText("Talk",1); + m_hints[2].WriteText("Use",1); +*/ + + // Prepara il primo inventario + Prepare(); + DrawOT(); + ClearOT(); +} + +void RMInventory::Close(void) { + // Ciao memoria + if (m_items != NULL) { + delete[] m_items; + m_items = NULL; + } + + Destroy(); +} + +void RMInventory::Reset(void) { + m_state = CLOSED; + EndCombine(); +} + +void RMInventory::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { + if (m_state == OPENING || m_state == CLOSING) + prim->SetDst(RMPoint(0, m_curPutY)); + else + prim->SetDst(RMPoint(0, m_curPutY)); + + g_system->lockMutex(m_csModifyInterface); + RMGfxWoodyBuffer::Draw(bigBuf, prim); + g_system->unlockMutex(m_csModifyInterface); + + if (m_state == SELECTING) { + RMPoint pos; + RMPoint pos2; + + if (!bCfgInvUp) { + pos.Set((m_nSelectObj+1)*64 - 20,RM_SY - 113); + pos2.Set((m_nSelectObj+1)*64 + 34,RM_SY - 150); + } else { + pos.Set((m_nSelectObj+1)*64 - 20, 72 - 4); // la parte marrone sta in alto :( + pos2.Set((m_nSelectObj+1)*64 + 34, 119 - 4); + } + + RMGfxPrimitive p(prim->m_task, pos); + RMGfxPrimitive p2(prim->m_task, pos2); + + // Disegna l'interfaccina stupida + miniInterface.Draw(bigBuf,&p); + + if (bCfgInterTips) { + if (miniAction == 1) // Esamina + m_hints[0].Draw(bigBuf, &p2); + else if (miniAction == 2) // Parla + m_hints[1].Draw(bigBuf, &p2); + else if (miniAction == 3) // Usa + m_hints[2].Draw(bigBuf, &p2); + } + } +} + +bool RMInventory::RemoveThis(void) { + if (m_state == CLOSED) + return true; + + return false; +} + +void RMInventory::RemoveItem(int code) { + int i; + + for (i=0;ilockMutex(m_csModifyInterface); + + Common::copy_backward(&m_inv[i + 1], &m_inv[i + 1] + (m_nInv - i), &m_inv[i]); +// m_inv[m_nInv-1]=0; + m_nInv--; + + Prepare(); + DrawOT(); + ClearOT(); + g_system->unlockMutex(m_csModifyInterface); + return; + } + + //MessageBox(NULL,"Specified object is not in the inventory","INTERNAL ERROR",MB_OK|MB_ICONEXCLAMATION); +} + +void RMInventory::AddItem(int code) { + if (code <= 10000 && code >= 10101) + { + // Se siamo qui, vuol dire che stiamo aggiungendo un oggetto che non dovrebbe essere + // nell'inventario + warning("Cannot find a valid icon for this item, and then it will not be added to the inventory"); + } else { + g_system->lockMutex(m_csModifyInterface); + if (m_curPos+8 == m_nInv) + { + // Sfondiamo l'inventario! Attivo il pattern di lampeggio + m_items[28].icon.SetPattern(2); + } + + m_inv[m_nInv++]=code-10000; + + Prepare(); + DrawOT(); + ClearOT(); + g_system->unlockMutex(m_csModifyInterface); + } +}; + +void RMInventory::ChangeItemStatus(uint32 code, uint32 dwStatus) { + if (code <= 10000 && code >= 10101) { + error("Specified object code is not valid"); + } else { + g_system->lockMutex(m_csModifyInterface); + m_items[code - 10000].icon.SetPattern(dwStatus); + m_items[code - 10000].status = dwStatus; + + Prepare(); + DrawOT(); + ClearOT(); + g_system->unlockMutex(m_csModifyInterface); + } +} + + +void RMInventory::Prepare(void) +{ + int i; + + for (i = 1; i < RM_SX / 64 - 1; i++) { + if (i - 1 + m_curPos < m_nInv) + AddPrim(new RMGfxPrimitive(&m_items[m_inv[i - 1 + m_curPos]].icon, RMPoint(i * 64, 0))); + else + AddPrim(new RMGfxPrimitive(&m_items[0].icon, RMPoint(i * 64, 0))); + } + + // Frecce + AddPrim(new RMGfxPrimitive(&m_items[29].icon, RMPoint(0, 0))); + AddPrim(new RMGfxPrimitive(&m_items[28].icon, RMPoint(640 - 64, 0))); + + //AddPrim(new RMGfxPrimitive(&m_items[0].icon,RMPoint(0,0))); +} + +bool RMInventory::MiniActive(void) { + return m_state == SELECTING; +} + +bool RMInventory::HaveFocus(RMPoint mpos) { + // In fase di combine abbiamo il focus solo se siamo su una freccia (per poter scrollare) + if (m_state == OPENED && m_bCombining && CheckPointInside(mpos) && (mpos.x < 64 || mpos.x > RM_SX - 64)) + return true; + + // Se l'inventario è aperto, abbiamo il focus quando ci andiamo sopra + if (m_state == OPENED && !m_bCombining && CheckPointInside(mpos)) + return true; + + // Se stiamo selezionando un verbo (quindi tasto destro premuto), abbiamo il focus alltime + if (m_state == SELECTING) + return true; + + return false; +} + +void RMInventory::EndCombine(void) { + m_bCombining = false; +} + +bool RMInventory::LeftClick(RMPoint mpos, int& nCombineObj) { + int n; + + // Il click sinistro prende in mano un oggetto dell'inventario per utilizzarlo con lo sfondo + n=mpos.x / 64; + + if (m_state == OPENED) { + if (n > 0 && n < RM_SX / 64 - 1 && m_inv[n - 1 + m_curPos] != 0) { + m_bCombining = true; //m_state=COMBINING; + m_nCombine = m_inv[n - 1 + m_curPos]; + nCombineObj = m_nCombine + 10000; + + _vm->PlayUtilSFX(1); + return true; + } + } + + // Click sulla freccia destra + if ((m_state == OPENED) && m_bBlinkingRight) + { + g_system->lockMutex(m_csModifyInterface); + m_curPos++; + + if (m_curPos+8 >= m_nInv) { + m_bBlinkingRight = false; + m_items[28].icon.SetPattern(1); + } + + if (m_curPos > 0) { + m_bBlinkingLeft = true; + m_items[29].icon.SetPattern(2); + } + + Prepare(); + DrawOT(); + ClearOT(); + g_system->unlockMutex(m_csModifyInterface); + } + // Click sulla freccia sinistra + else if ((m_state == OPENED) && m_bBlinkingLeft) { + assert(m_curPos>0); + g_system->lockMutex(m_csModifyInterface); + m_curPos--; + + if (m_curPos == 0) { + m_bBlinkingLeft = false; + m_items[29].icon.SetPattern(1); + } + + if (m_curPos + 8 < m_nInv) { + m_bBlinkingRight = true; + m_items[28].icon.SetPattern(2); + } + + Prepare(); + DrawOT(); + ClearOT(); + g_system->unlockMutex(m_csModifyInterface); + } + + + return false; +} + + +void RMInventory::RightClick(RMPoint mpos) { + int n; + + assert(CheckPointInside(mpos)); + + if (m_state == OPENED && !m_bCombining) { + // Apre l'interfaccina contestuale + n = mpos.x / 64; + + if (n > 0 && n < RM_SX / 64-1 && m_inv[n-1+m_curPos]!=0) + { + m_state=SELECTING; + miniAction=0; + m_nSelectObj=n-1; + + _vm->PlayUtilSFX(0); + } + } + + if ((m_state == OPENED) && m_bBlinkingRight) { + g_system->lockMutex(m_csModifyInterface); + m_curPos += 7; + if (m_curPos + 8 > m_nInv) + m_curPos = m_nInv - 8; + + if (m_curPos + 8 <= m_nInv) { + m_bBlinkingRight = false; + m_items[28].icon.SetPattern(1); + } + + if (m_curPos>0) { + m_bBlinkingLeft = true; + m_items[29].icon.SetPattern(2); + } + + Prepare(); + DrawOT(); + ClearOT(); + g_system->unlockMutex(m_csModifyInterface); + } else if ((m_state == OPENED) && m_bBlinkingLeft) { + assert(m_curPos > 0); + g_system->lockMutex(m_csModifyInterface); + m_curPos -= 7; + if (m_curPos < 0) m_curPos = 0; + + if (m_curPos == 0) { + m_bBlinkingLeft = false; + m_items[29].icon.SetPattern(1); + } + + if (m_curPos + 8 < m_nInv) { + m_bBlinkingRight = true; + m_items[28].icon.SetPattern(2); + } + + Prepare(); + DrawOT(); + ClearOT(); + g_system->unlockMutex(m_csModifyInterface); + } +} + +bool RMInventory::RightRelease(RMPoint mpos, RMTonyAction& curAction) { + if (m_state == SELECTING) { + m_state = OPENED; + + if (miniAction == 1) { // Esamina + curAction = TA_EXAMINE; + return true; + } else if (miniAction == 2) { // Parla + curAction = TA_TALK; + return true; + } else if (miniAction == 3) { // Usa + curAction = TA_USE; + return true; + } + } + + return false; +} + +#define INVSPEED 20 + +void RMInventory::DoFrame(RMGfxTargetBuffer &bigBuf, RMPointer &ptr, RMPoint mpos, bool bCanOpen) { + int i; + bool bNeedRedraw = false; + + if (m_state != CLOSED) { + // Pulisce l'OTList + g_system->lockMutex(m_csModifyInterface); + ClearOT(); + + // Fa il DoFrame di tutti gli oggetti contenuti attualmente nell'inventario + // @@@ forse bisognerebbe farlo di tutti gli oggetti takeable? Probabilmente non serve a nulla + for (i = 0; i < m_nInv; i++) + if (m_items[m_inv[i]].icon.DoFrame(this, false) && (i >= m_curPos && i <= m_curPos + 7)) + bNeedRedraw = true; + + if ((m_state == CLOSING || m_state == OPENING || m_state == OPENED) && CheckPointInside(mpos)) { + if (mpos.x > RM_SX - 64) { + if (m_curPos + 8 < m_nInv && !m_bBlinkingRight) { + m_items[28].icon.SetPattern(3); + m_bBlinkingRight = true; + bNeedRedraw = true; + } + } else if (m_bBlinkingRight) { + m_items[28].icon.SetPattern(2); + m_bBlinkingRight = false; + bNeedRedraw = true; + } + + if (mpos.x < 64) { + if (m_curPos > 0 && !m_bBlinkingLeft) { + m_items[29].icon.SetPattern(3); + m_bBlinkingLeft = true; + bNeedRedraw = true; + } + } else if (m_bBlinkingLeft) { + m_items[29].icon.SetPattern(2); + m_bBlinkingLeft = false; + bNeedRedraw = true; + } + } + + if (m_items[28].icon.DoFrame(this, false)) + bNeedRedraw = true; + + if (m_items[29].icon.DoFrame(this, false)) + bNeedRedraw = true; + + if (bNeedRedraw) + Prepare(); + + g_system->unlockMutex(m_csModifyInterface); + } + + if ((GetAsyncKeyState(Common::KEYCODE_i) & 0x8001) == 0x8001) { + bCfgInvLocked = !bCfgInvLocked; + } + + if (m_bCombining) {//m_state == COMBINING) + ptr.SetCustomPointer(&m_items[m_nCombine].pointer[m_items[m_nCombine].status - 1]); + ptr.SetSpecialPointer(RMPointer::PTR_CUSTOM); + } + + if (!bCfgInvUp) { + if ((m_state == CLOSED) && (mpos.y > RM_SY - 10 || bCfgInvLocked) && bCanOpen) { + if (!bCfgInvNoScroll) { + m_state = OPENING; + m_curPutY = RM_SY - 1; + m_curPutTime=_vm->GetTime(); + } else { + m_state = OPENED; + m_curPutY = RM_SY - 68; + } + } else if (m_state == OPENED) { + if ((mpos.y < RM_SY - 70 && !bCfgInvLocked) || !bCanOpen) { + if (!bCfgInvNoScroll) { + m_state = CLOSING; + m_curPutY = RM_SY - 68; + m_curPutTime = _vm->GetTime(); + } else { + m_state = CLOSED; + } + } + } else if (m_state == OPENING) { + while (m_curPutTime + INVSPEED < _vm->GetTime()) { + m_curPutY -= 3; + m_curPutTime += INVSPEED; + } + + if (m_curPutY <= RM_SY - 68) { + m_state = OPENED; + m_curPutY = RM_SY - 68; + } + + } else if (m_state == CLOSING) { + while (m_curPutTime + INVSPEED < _vm->GetTime()) { + m_curPutY += 3; + m_curPutTime += INVSPEED; + } + + if (m_curPutY > 480) + m_state = CLOSED; + } + } else { + if ((m_state == CLOSED) && (mpos.y<10 || bCfgInvLocked) && bCanOpen) { + if (!bCfgInvNoScroll) { + m_state = OPENING; + m_curPutY =- 68; + m_curPutTime = _vm->GetTime(); + } else { + m_state = OPENED; + m_curPutY = 0; + } + } + else if (m_state == OPENED) { + if ((mpos.y>70 && !bCfgInvLocked) || !bCanOpen) { + if (!bCfgInvNoScroll) { + m_state = CLOSING; + m_curPutY = -2; + m_curPutTime = _vm->GetTime(); + } else { + m_state = CLOSED; + } + } + } else if (m_state == OPENING) { + while (m_curPutTime + INVSPEED < _vm->GetTime()) { + m_curPutY += 3; + m_curPutTime += INVSPEED; + } + + if (m_curPutY >= 0) { + m_state = OPENED; + m_curPutY = 0; + } + } else if (m_state == CLOSING) { + while (m_curPutTime + INVSPEED < _vm->GetTime()) { + m_curPutY -= 3; + m_curPutTime += INVSPEED; + } + + if (m_curPutY < -68) + m_state = CLOSED; + } + } + + if (m_state == SELECTING) { + int startx = (m_nSelectObj + 1) * 64 - 20; + int starty; + + if (!bCfgInvUp) + starty=RM_SY-109; + else + starty=70; + + // Controlla se si trova su uno dei verbi + if (mpos.y > starty && mpos.y < starty + 45) { + if (mpos.x > startx && mpos.x < startx + 40) { + if (miniAction !=1 ) { + miniInterface.SetPattern(2); + miniAction = 1; + _vm->PlayUtilSFX(1); + } + } else if (mpos.x >= startx + 40 && mpos.x < startx + 80) { + if (miniAction != 2) { + miniInterface.SetPattern(3); + miniAction = 2; + _vm->PlayUtilSFX(1); + } + } else if (mpos.x >= startx + 80 && mpos.x < startx + 108) { + if (miniAction != 3) { + miniInterface.SetPattern(4); + miniAction = 3; + _vm->PlayUtilSFX(1); + } + } else { + miniInterface.SetPattern(1); + miniAction = 0; + } + } else { + miniInterface.SetPattern(1); + miniAction = 0; + } + + // Aggiorna la miniinterface + miniInterface.DoFrame(&bigBuf, false); + } + + if ((m_state!= CLOSED) && !m_nInList) { + bigBuf.AddPrim(new RMGfxPrimitive(this)); + } +} + + +bool RMInventory::ItemInFocus(RMPoint mpt) { + if ((m_state == OPENED || m_state == OPENING) && CheckPointInside(mpt)) + return true; + else + return false; +} + +RMItem *RMInventory::WhichItemIsIn(RMPoint mpt) { + int n; + + if (m_state == OPENED) { + if (CheckPointInside(mpt)) { + n=mpt.x / 64; + if (n>0 && n < RM_SX / 64 - 1 && m_inv[n - 1 + m_curPos] != 0 && (!m_bCombining || m_inv[n - 1 + m_curPos] != m_nCombine)) + return &m_items[m_inv[n - 1 + m_curPos]].icon; + } + } + + return NULL; +} + + + +int RMInventory::GetSaveStateSize(void) { + // m_inv pattern m_nInv + return 256*4 + 256*4 + 4 ; +} + +void RMInventory::SaveState(byte *state) { + int i, x; + + WRITE_LE_UINT32(state, m_nInv); state += 4; + Common::copy(m_inv, m_inv + 256, (uint32 *)state); state += 256 * 4; + + for (i = 0; i < 256; i++) { + if (i < m_nItems) + x = m_items[i].status; + else + x = 0; + + WRITE_LE_UINT32(state, x); state += 4; + } +} + +int RMInventory::LoadState(byte *state) { + int i, x; + + m_nInv = READ_LE_UINT32(state); state += 4; + Common::copy((uint32 *)state, (uint32 *)state + 256, m_inv); state += 256 * 4; + + for (i = 0; i < 256; i++) { + x = READ_LE_UINT32(state); state += 4; + + if (i < m_nItems) { + m_items[i].status = x; + m_items[i].icon.SetPattern(x); + } + } + + m_curPos = 0; + m_bCombining = false; + + m_items[29].icon.SetPattern(1); + + if (m_nInv > 8) + m_items[28].icon.SetPattern(2); + else + m_items[28].icon.SetPattern(1); + + Prepare(); + DrawOT(); + ClearOT(); + + return GetSaveStateSize(); +} + + +/****************************************************************************\ +* RMInterface methods +\****************************************************************************/ + +RMInterface::~RMInterface() { + +} + +bool RMInterface::Active() { + return m_bActive; +} + +int RMInterface::OnWhichBox(RMPoint pt) { + int max, i; + + pt -= m_openStart; + + // Controlla quanti verbi bisogna considerare + max = 4; if (m_bPalesati) max = 5; + + // Cerca il verbo + for (i = 0; i < max; i++) + if (m_hotbbox[i].PtInRect(pt)) + return i; + + // Nessun verbo trovato + return -1; +} + +void RMInterface::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { + int h; + + prim->Dst().TopLeft() = m_openStart; + RMGfxSourceBuffer8RLEByte::Draw(bigBuf, prim); + + // Controlla se c'e' da disegnare una zona calda + h = OnWhichBox(m_mpos); + if (h != -1) { + prim->Dst().TopLeft() = m_openStart; + m_hotzone[h].Draw(bigBuf, prim); + + if (m_lastHotZone != h) { + m_lastHotZone = h; + _vm->PlayUtilSFX(1); + } + + if (bCfgInterTips) { + prim->Dst().TopLeft() = m_openStart + RMPoint(70, 177); + m_hints[h].Draw(bigBuf,prim); + } + } else + m_lastHotZone = -1; + +} + + +void RMInterface::DoFrame(RMGfxTargetBuffer &bigBuf, RMPoint mousepos) { + // Se c'è bisogna, schedula nella OT list + if (!m_nInList && m_bActive) + bigBuf.AddPrim(new RMGfxPrimitive(this)); + + m_mpos = mousepos; +} + +void RMInterface::Clicked(RMPoint mousepos) { + m_bActive = true; + m_openPos = mousepos; + + // Calcola l'angolo in alto a sinistra dell'interfaccia + m_openStart = m_openPos - RMPoint(m_dimx / 2, m_dimy / 2); + m_lastHotZone = -1; + + // La tiene dentro lo schermo + if (m_openStart.x < 0) m_openStart.x = 0; + if (m_openStart.y < 0) m_openStart.y = 0; + if (m_openStart.x+m_dimx > RM_SX) m_openStart.x = RM_SX - m_dimx; + if (m_openStart.y+m_dimy > RM_SY) m_openStart.y = RM_SY - m_dimy; + + // Play dell'effetto sonoro + _vm->PlayUtilSFX(0); +} + +bool RMInterface::Released(RMPoint mousepos, RMTonyAction &action) { + if (!m_bActive) + return false; + + m_bActive = false; + + switch (OnWhichBox(mousepos)) { + case 0: + action = TA_TAKE; + break; + + case 1: + action = TA_TALK; + break; + + case 2: + action = TA_USE; + break; + + case 3: + action = TA_EXAMINE; + break; + + case 4: + action = TA_PALESATI; + break; + + default: // Nessun verbo + return false; + } + + return true; +} + +void RMInterface::Reset(void) { + m_bActive = false; +} + +void RMInterface::SetPalesati(bool bOn) { + m_bPalesati=bOn; +} + +bool RMInterface::GetPalesati(void) { + return m_bPalesati; +} + +void RMInterface::Init(void) { + int i; + RMResRaw inter(RES_I_INTERFACE); + RMRes pal(RES_I_INTERPPAL); + + SetPriority(191); + + RMGfxSourceBuffer::Init(inter, inter.Width(), inter.Height()); + LoadPaletteWA(RES_I_INTERPAL); + + for (i = 0; i < 5; i++) { + RMResRaw part(RES_I_INTERP1 + i); + + m_hotzone[i].Init(part, part.Width(), part.Height()); + m_hotzone[i].LoadPaletteWA(pal); + } + + m_hotbbox[0].SetRect(126, 123, 159, 208); // prendi + m_hotbbox[1].SetRect(90, 130, 125, 186); // parla + m_hotbbox[2].SetRect(110, 60, 152, 125); + m_hotbbox[3].SetRect(56, 51, 93, 99); + m_hotbbox[4].SetRect(51, 105, 82, 172); + + m_hints[0].SetAlignType(RMText::HRIGHT, RMText::VTOP); + m_hints[1].SetAlignType(RMText::HRIGHT, RMText::VTOP); + m_hints[2].SetAlignType(RMText::HRIGHT, RMText::VTOP); + m_hints[3].SetAlignType(RMText::HRIGHT, RMText::VTOP); + m_hints[4].SetAlignType(RMText::HRIGHT, RMText::VTOP); + + // Il testo viene preso da MPAL per la traduzione + RMMessage msg0(12); + RMMessage msg1(13); + RMMessage msg2(14); + RMMessage msg3(15); + RMMessage msg4(16); + + m_hints[0].WriteText(msg0[0], 1); + m_hints[1].WriteText(msg1[0], 1); + m_hints[2].WriteText(msg2[0], 1); + m_hints[3].WriteText(msg3[0], 1); + m_hints[4].WriteText(msg4[0], 1); +/* + m_hints[0].WriteText("Take",1); + m_hints[1].WriteText("Talk",1); + m_hints[2].WriteText("Use",1); + m_hints[3].WriteText("Examine",1); + m_hints[4].WriteText("Palesati",1); +*/ + m_bActive = false; + m_bPalesati = false; +} + +void RMInterface::Close(void) { + int i; + + Destroy(); + + for (i = 0; i < 5; i++) + m_hotzone[i].Destroy(); +} + +} // End of namespace Tony diff --git a/engines/tony/inventory.h b/engines/tony/inventory.h index 5ec67f6228..3d8650773f 100644 --- a/engines/tony/inventory.h +++ b/engines/tony/inventory.h @@ -51,6 +51,7 @@ #include "common/scummsys.h" #include "common/system.h" #include "tony/font.h" +#include "tony/game.h" #include "tony/gfxcore.h" #include "tony/loc.h" @@ -79,7 +80,7 @@ protected: int m_inv[256]; int m_nInv; int m_curPutY; - int m_curPutTime; + uint32 m_curPutTime; int m_curPos; STATE m_state; @@ -134,7 +135,7 @@ public: // Gestisce il tasto destro del mouse (solo quando c'ha focus) void RightClick(RMPoint mpos); - bool RightRelease(RMPoint mpos, RMTonyAction& curAction); + bool RightRelease(RMPoint mpos, RMTonyAction &curAction); // Avverte che è finito il combine void EndCombine(void); diff --git a/engines/tony/module.mk b/engines/tony/module.mk index cbd44d467e..f7d8b1e8c1 100644 --- a/engines/tony/module.mk +++ b/engines/tony/module.mk @@ -7,6 +7,7 @@ MODULE_OBJS := \ gfxcore.o \ gfxengine.o \ input.o \ + inventory.o \ loc.o \ sound.o \ tony.o \ diff --git a/engines/tony/utils.cpp b/engines/tony/utils.cpp index 360b7a6f32..43a129b92a 100644 --- a/engines/tony/utils.cpp +++ b/engines/tony/utils.cpp @@ -816,19 +816,19 @@ RMPoint RMRect::Center() { return RMPoint((x2 - x1) / 2,(y2 - y1) / 2); } -int RMRect::Width() { +int RMRect::Width() const { return x2 - x1; } -int RMRect::Height() { +int RMRect::Height() const { return y2 - y1; } -int RMRect::Size() { +int RMRect::Size() const { return Width() * Height(); } -bool RMRect::IsEmpty() { +bool RMRect::IsEmpty() const { return (x1 == 0 && y1 == 0 && x2 == 0 && y2 == 0); } diff --git a/engines/tony/utils.h b/engines/tony/utils.h index 54e4cd0eae..bd4b152f1f 100644 --- a/engines/tony/utils.h +++ b/engines/tony/utils.h @@ -232,10 +232,10 @@ public: RMPoint &TopLeft(); RMPoint &BottomRight(); RMPoint Center(); - int Width(); - int Height(); - bool IsEmpty(); - int Size(); + int Width() const; + int Height() const; + bool IsEmpty() const; + int Size() const; // Set void SetRect(int x1, int y1, int x2, int y2); -- cgit v1.2.3