2012-04-30 09:27:12 +10:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
2012-05-14 07:43:50 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This code is based on original Tony Tough source code
|
|
|
|
*
|
|
|
|
* Copyright (c) 1997-2003 Nayma Software
|
|
|
|
*/
|
2012-04-30 09:27:12 +10:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
#include "common/savefile.h"
|
|
|
|
#include "tony/mpal/lzo.h"
|
|
|
|
#include "tony/mpal/mpalutils.h"
|
|
|
|
#include "tony/custom.h"
|
2012-05-04 22:09:24 +10:00
|
|
|
#include "tony/gfxengine.h"
|
2012-05-01 23:00:03 +10:00
|
|
|
#include "tony/tony.h"
|
2012-04-30 09:27:12 +10:00
|
|
|
|
|
|
|
namespace Tony {
|
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
/****************************************************************************\
|
2012-05-20 15:28:48 +10:00
|
|
|
* RMGfxEngine Methods
|
2012-05-01 23:00:03 +10:00
|
|
|
\****************************************************************************/
|
|
|
|
|
2012-05-09 00:42:27 +10:00
|
|
|
void ExitAllIdles(CORO_PARAM, const void *param) {
|
2012-05-06 15:18:03 +10:00
|
|
|
CORO_BEGIN_CONTEXT;
|
|
|
|
CORO_END_CONTEXT(_ctx);
|
|
|
|
|
2012-05-09 00:42:27 +10:00
|
|
|
int nCurLoc = *(const int *)param;
|
|
|
|
|
2012-05-06 15:18:03 +10:00
|
|
|
CORO_BEGIN_CODE(_ctx);
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Closes idle
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bSkipSfxNoLoop = true;
|
2012-05-06 15:18:03 +10:00
|
|
|
|
|
|
|
CORO_INVOKE_2(mpalEndIdlePoll, nCurLoc, NULL);
|
|
|
|
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bIdleExited = true;
|
|
|
|
GLOBALS.bSkipSfxNoLoop = false;
|
2012-05-06 15:18:03 +10:00
|
|
|
|
|
|
|
CORO_END_CODE;
|
2012-05-03 22:49:30 +10:00
|
|
|
}
|
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
RMGfxEngine::RMGfxEngine() {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Create big buffer where the frame will be rendered
|
2012-05-03 22:49:30 +10:00
|
|
|
m_bigBuf.Create(RM_BBX, RM_BBY, 16);
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bigBuf.OffsetY(RM_SKIPY);
|
2012-05-05 10:32:43 +10:00
|
|
|
|
|
|
|
csMainLoop = NULL;
|
2012-05-13 09:42:09 +10:00
|
|
|
m_nCurLoc = 0;
|
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_curActionObj = 0;
|
2012-05-14 21:29:27 +02:00
|
|
|
m_nWipeType = 0;
|
2012-05-13 09:42:09 +10:00
|
|
|
m_hWipeEvent = 0;
|
2012-05-14 21:29:27 +02:00
|
|
|
m_nWipeStep = 0;
|
2012-05-13 09:42:09 +10:00
|
|
|
m_bMustEnterMenu = false;
|
|
|
|
m_bWiping = false;
|
|
|
|
m_bGUIOption = false;
|
|
|
|
m_bGUIInterface = false;
|
|
|
|
m_bGUIInventory = false;
|
2012-05-13 09:58:07 +10:00
|
|
|
m_bAlwaysDrawMouse = false;
|
|
|
|
m_bOption = false;
|
|
|
|
m_bLocationLoaded = false;
|
|
|
|
m_bInput = false;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
RMGfxEngine::~RMGfxEngine() {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Close the buffer
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bigBuf.Destroy();
|
2012-05-05 10:32:43 +10:00
|
|
|
g_system->deleteMutex(csMainLoop);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 00:42:27 +10:00
|
|
|
void RMGfxEngine::OpenOptionScreen(CORO_PARAM, int type) {
|
|
|
|
CORO_BEGIN_CONTEXT;
|
2012-05-14 21:29:27 +02:00
|
|
|
bool bRes;
|
2012-05-09 00:42:27 +10:00
|
|
|
CORO_END_CONTEXT(_ctx);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-09 00:42:27 +10:00
|
|
|
CORO_BEGIN_CODE(_ctx);
|
|
|
|
|
|
|
|
_ctx->bRes = false;
|
|
|
|
|
|
|
|
if (type == 0)
|
2012-05-12 20:49:36 +10:00
|
|
|
CORO_INVOKE_2(m_opt.Init, m_bigBuf, _ctx->bRes);
|
2012-05-09 00:42:27 +10:00
|
|
|
else if (type == 1)
|
2012-05-12 20:49:36 +10:00
|
|
|
CORO_INVOKE_3(m_opt.InitLoadMenuOnly, m_bigBuf, true, _ctx->bRes);
|
2012-05-09 00:42:27 +10:00
|
|
|
else if (type == 2)
|
2012-05-12 20:49:36 +10:00
|
|
|
CORO_INVOKE_2(m_opt.InitNoLoadSave, m_bigBuf, _ctx->bRes);
|
2012-05-09 00:42:27 +10:00
|
|
|
else if (type == 3)
|
2012-05-12 20:49:36 +10:00
|
|
|
CORO_INVOKE_3(m_opt.InitLoadMenuOnly, m_bigBuf, false, _ctx->bRes);
|
2012-05-09 00:42:27 +10:00
|
|
|
else if (type == 4)
|
2012-05-12 20:49:36 +10:00
|
|
|
CORO_INVOKE_3(m_opt.InitSaveMenuOnly, m_bigBuf, false, _ctx->bRes);
|
2012-05-09 00:42:27 +10:00
|
|
|
|
|
|
|
if (_ctx->bRes) {
|
2012-06-04 23:45:36 +02:00
|
|
|
_vm->pauseSound(true);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
DisableInput();
|
|
|
|
m_inv.EndCombine();
|
|
|
|
m_curActionObj = 0;
|
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_point.SetAction(m_curAction);
|
|
|
|
m_point.SetSpecialPointer(RMPointer::PTR_NONE);
|
|
|
|
m_point.SetCustomPointer(NULL);
|
|
|
|
EnableMouse();
|
2012-06-04 23:45:36 +02:00
|
|
|
_vm->grabThumbnail();
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Exists the IDLE to avoid premature death in loading
|
2012-05-14 21:29:27 +02:00
|
|
|
m_bMustEnterMenu = true;
|
2012-05-01 23:00:03 +10:00
|
|
|
if (type == 1 || type == 2) {
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bIdleExited = true;
|
2012-05-01 23:00:03 +10:00
|
|
|
} else {
|
2012-05-09 00:42:27 +10:00
|
|
|
CORO_INVOKE_0(m_tony.StopNoAction);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bIdleExited = false;
|
2012-05-09 00:42:27 +10:00
|
|
|
|
2012-05-11 23:15:59 +10:00
|
|
|
CoroScheduler.createProcess(ExitAllIdles, &m_nCurLoc, sizeof(int));
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
}
|
2012-05-09 00:42:27 +10:00
|
|
|
|
|
|
|
CORO_END_CODE;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 00:42:27 +10:00
|
|
|
void RMGfxEngine::DoFrame(CORO_PARAM, bool bDrawLocation) {
|
|
|
|
CORO_BEGIN_CONTEXT;
|
|
|
|
CORO_END_CONTEXT(_ctx);
|
|
|
|
|
|
|
|
CORO_BEGIN_CODE(_ctx);
|
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
g_system->lockMutex(csMainLoop);
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Poll of input devices
|
2012-06-05 00:02:15 +02:00
|
|
|
m_input.poll();
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-13 22:34:40 +10:00
|
|
|
if (m_bMustEnterMenu && GLOBALS.bIdleExited) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bOption = true;
|
|
|
|
m_bMustEnterMenu = false;
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bIdleExited = false;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
2012-05-14 21:29:27 +02:00
|
|
|
|
|
|
|
if (m_bOption) {
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_INVOKE_1(m_opt.DoFrame, &m_input);
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bOption = !m_opt.IsClosing();
|
|
|
|
if (!m_bOption) {
|
|
|
|
DisableMouse();
|
|
|
|
EnableInput();
|
|
|
|
mpalStartIdlePoll(m_nCurLoc);
|
2012-06-04 23:45:36 +02:00
|
|
|
_vm->pauseSound(false);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bDrawLocation && m_bLocationLoaded) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Location and objects
|
2012-05-01 23:00:03 +10:00
|
|
|
m_loc.DoFrame(&m_bigBuf);
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Check the mouse input
|
2012-05-01 23:00:03 +10:00
|
|
|
if (m_bInput && !m_tony.InAction()) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// If we are on the inventory, it is it who controls all input
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_inv.HaveFocus(m_input.mousePos()) && !m_inter.Active()) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Left Click
|
|
|
|
// **********
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_input.mouseLeftClicked()/* && m_itemName.IsItemSelected()*/) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Left click activates the combine, if we are on an object
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_inv.LeftClick(m_input.mousePos(), m_curActionObj)) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_curAction = TA_COMBINE;
|
|
|
|
m_point.SetAction(m_curAction);
|
|
|
|
}
|
2012-05-14 21:29:27 +02:00
|
|
|
} else
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Right Click
|
|
|
|
// ***********
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_input.mouseRightClicked()) {
|
2012-05-14 21:29:27 +02:00
|
|
|
if (m_itemName.IsItemSelected()) {
|
|
|
|
m_curActionObj = 0;
|
2012-06-05 00:02:15 +02:00
|
|
|
m_inv.RightClick(m_input.mousePos());
|
2012-05-14 21:29:27 +02:00
|
|
|
} else
|
2012-06-05 00:02:15 +02:00
|
|
|
m_inv.RightClick(m_input.mousePos());
|
2012-05-01 23:00:03 +10:00
|
|
|
} else
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Right Release
|
|
|
|
// *************
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_input.mouseRightReleased()) {
|
|
|
|
if (m_inv.RightRelease(m_input.mousePos(), m_curAction)) {
|
2012-05-14 21:29:27 +02:00
|
|
|
CORO_INVOKE_3(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), m_curAction);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-14 21:29:27 +02:00
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_point.SetAction(m_curAction);
|
|
|
|
}
|
|
|
|
}
|
2012-05-01 23:00:03 +10:00
|
|
|
} else {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Options Menu
|
2012-05-01 23:00:03 +10:00
|
|
|
// ************
|
|
|
|
if (m_bGUIOption) {
|
|
|
|
if (!m_tony.InAction() && m_bInput) {
|
2012-06-05 00:02:15 +02:00
|
|
|
if ((m_input.mouseLeftClicked() && m_input.mousePos().x < 3 && m_input.mousePos().y < 3)) {
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_INVOKE_1(OpenOptionScreen, 0);
|
2012-05-01 23:00:03 +10:00
|
|
|
goto SKIPCLICKSINISTRO;
|
2012-06-05 00:02:15 +02:00
|
|
|
} else if (m_input.getAsyncKeyState(Common::KEYCODE_ESCAPE))
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_INVOKE_1(OpenOptionScreen, 0);
|
2012-05-12 20:49:36 +10:00
|
|
|
else if (!_vm->getIsDemo()) {
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_input.getAsyncKeyState(Common::KEYCODE_F3) || m_input.getAsyncKeyState(Common::KEYCODE_F5))
|
2012-05-12 20:49:36 +10:00
|
|
|
// Save game screen
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_INVOKE_1(OpenOptionScreen, 3);
|
2012-06-05 00:02:15 +02:00
|
|
|
else if (m_input.getAsyncKeyState(Common::KEYCODE_F2) || m_input.getAsyncKeyState(Common::KEYCODE_F7))
|
2012-05-12 20:49:36 +10:00
|
|
|
// Load game screen
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_INVOKE_1(OpenOptionScreen, 4);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Left Click
|
2012-05-01 23:00:03 +10:00
|
|
|
// **************
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_input.mouseLeftClicked() && !m_inter.Active()) {
|
2012-05-20 16:34:38 +10:00
|
|
|
|
|
|
|
if (m_curAction != TA_COMBINE)
|
|
|
|
CORO_INVOKE_3(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), m_point.CurAction());
|
|
|
|
else if (m_itemName.GetSelectedItem() != NULL)
|
|
|
|
CORO_INVOKE_4(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), TA_COMBINE, m_curActionObj);
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
if (m_curAction == TA_COMBINE) {
|
|
|
|
m_inv.EndCombine();
|
|
|
|
m_point.SetSpecialPointer(RMPointer::PTR_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_point.SetAction(m_curAction);
|
|
|
|
}
|
|
|
|
|
|
|
|
SKIPCLICKSINISTRO:
|
2012-05-20 15:28:48 +10:00
|
|
|
// Right Click
|
2012-05-01 23:00:03 +10:00
|
|
|
// ************
|
|
|
|
if (m_curAction == TA_COMBINE) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// During a combine, it cancels it
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_input.mouseRightClicked()) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_inv.EndCombine();
|
|
|
|
m_curActionObj = 0;
|
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_point.SetAction(m_curAction);
|
|
|
|
m_point.SetSpecialPointer(RMPointer::PTR_NONE);
|
|
|
|
}
|
2012-06-05 00:02:15 +02:00
|
|
|
} else if (m_input.mouseRightClicked() && m_itemName.IsItemSelected() && m_point.GetSpecialPointer() == RMPointer::PTR_NONE) {
|
2012-05-01 23:00:03 +10:00
|
|
|
if (m_bGUIInterface) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Before opening the interface, replaces GOTO
|
2012-05-01 23:00:03 +10:00
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_curActionObj = 0;
|
|
|
|
m_point.SetAction(m_curAction);
|
2012-06-05 00:02:15 +02:00
|
|
|
m_inter.Clicked(m_input.mousePos());
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
}
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Right Release
|
|
|
|
// *************
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_input.mouseRightReleased()) {
|
2012-05-01 23:00:03 +10:00
|
|
|
if (m_bGUIInterface) {
|
2012-06-05 00:02:15 +02:00
|
|
|
if (m_inter.Released(m_input.mousePos(), m_curAction)) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_point.SetAction(m_curAction);
|
2012-05-11 00:09:34 +10:00
|
|
|
CORO_INVOKE_3(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), m_curAction);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_point.SetAction(m_curAction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Update the name under the mouse pointer
|
2012-06-05 00:02:15 +02:00
|
|
|
m_itemName.SetMouseCoord(m_input.mousePos());
|
2012-05-01 23:00:03 +10:00
|
|
|
if (!m_inter.Active() && !m_inv.MiniActive())
|
2012-05-14 21:29:27 +02:00
|
|
|
CORO_INVOKE_4(m_itemName.DoFrame, m_bigBuf, m_loc, m_point, m_inv);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Interface & Inventory
|
2012-06-05 00:02:15 +02:00
|
|
|
m_inter.DoFrame(m_bigBuf, m_input.mousePos());
|
|
|
|
m_inv.DoFrame(m_bigBuf, m_point, m_input.mousePos(), (!m_tony.InAction() && !m_inter.Active() && m_bGUIInventory));
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Animate Tony
|
2012-05-11 00:09:34 +10:00
|
|
|
CORO_INVOKE_2(m_tony.DoFrame, &m_bigBuf, m_nCurLoc);
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Update screen scrolling to keep Tony in focus
|
2012-05-01 23:00:03 +10:00
|
|
|
if (m_tony.MustUpdateScrolling() && m_bLocationLoaded) {
|
|
|
|
RMPoint showThis = m_tony.Position();
|
|
|
|
showThis.y -= 60;
|
|
|
|
m_loc.UpdateScrolling(showThis);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_bLocationLoaded)
|
|
|
|
m_tony.SetScrollPosition(m_loc.ScrollPosition());
|
|
|
|
|
|
|
|
if ((!m_tony.InAction() && m_bInput) || m_bAlwaysDrawMouse) {
|
2012-06-05 00:02:15 +02:00
|
|
|
m_point.SetCoord(m_input.mousePos());
|
2012-05-01 23:00:03 +10:00
|
|
|
m_point.DoFrame(&m_bigBuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
// **********************
|
2012-05-20 15:28:48 +10:00
|
|
|
// Draw the list in the OT
|
2012-05-01 23:00:03 +10:00
|
|
|
// **********************
|
2012-05-13 15:50:15 +10:00
|
|
|
CORO_INVOKE_0(m_bigBuf.DrawOT);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
#define FSTEP (480/32)
|
|
|
|
|
|
|
|
// Wipe
|
|
|
|
if (m_bWiping) {
|
|
|
|
switch (m_nWipeType) {
|
2012-05-14 21:29:27 +02:00
|
|
|
case 1:
|
|
|
|
if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top >= FSTEP * 2)) {
|
|
|
|
CoroScheduler.setEvent(m_hWipeEvent);
|
|
|
|
m_nWipeType = 3;
|
2012-05-01 23:00:03 +10:00
|
|
|
break;
|
2012-05-14 21:29:27 +02:00
|
|
|
}
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-14 21:29:27 +02:00
|
|
|
m_rcWipeEllipse.top += FSTEP;
|
|
|
|
m_rcWipeEllipse.left += FSTEP;
|
|
|
|
m_rcWipeEllipse.right -= FSTEP;
|
|
|
|
m_rcWipeEllipse.bottom -= FSTEP;
|
|
|
|
break;
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-14 21:29:27 +02:00
|
|
|
case 2:
|
|
|
|
if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top < 480 - FSTEP)) {
|
|
|
|
CoroScheduler.setEvent(m_hWipeEvent);
|
|
|
|
m_nWipeType = 3;
|
2012-05-01 23:00:03 +10:00
|
|
|
break;
|
2012-05-14 21:29:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
m_rcWipeEllipse.top -= FSTEP;
|
|
|
|
m_rcWipeEllipse.left -= FSTEP;
|
|
|
|
m_rcWipeEllipse.right += FSTEP;
|
|
|
|
m_rcWipeEllipse.bottom += FSTEP;
|
|
|
|
break;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_system->unlockMutex(csMainLoop);
|
2012-05-09 00:42:27 +10:00
|
|
|
|
|
|
|
CORO_END_CODE;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RMGfxEngine::InitCustomDll(void) {
|
|
|
|
SetupGlobalVars(&m_tony, &m_point, &_vm->_theBoxes, &m_loc, &m_inv, &m_input);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RMGfxEngine::ItemIrq(uint32 dwItem, int nPattern, int nStatus) {
|
|
|
|
RMItem *item;
|
2012-05-14 20:20:02 +10:00
|
|
|
assert(GLOBALS.GfxEngine);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-14 20:20:02 +10:00
|
|
|
if (GLOBALS.GfxEngine->m_bLocationLoaded) {
|
|
|
|
item = GLOBALS.GfxEngine->m_loc.GetItemFromCode(dwItem);
|
2012-05-01 23:00:03 +10:00
|
|
|
if (item != NULL) {
|
2012-05-14 20:20:02 +10:00
|
|
|
if (nPattern != -1) {
|
2012-05-13 22:34:40 +10:00
|
|
|
if (GLOBALS.bPatIrqFreeze)
|
2012-05-01 23:00:03 +10:00
|
|
|
MainFreeze();
|
2012-05-14 21:29:27 +02:00
|
|
|
item->SetPattern(nPattern, true);
|
2012-05-13 22:34:40 +10:00
|
|
|
if (GLOBALS.bPatIrqFreeze)
|
2012-05-01 23:00:03 +10:00
|
|
|
MainUnfreeze();
|
|
|
|
}
|
2012-05-14 20:20:02 +10:00
|
|
|
if (nStatus != -1)
|
2012-05-01 23:00:03 +10:00
|
|
|
item->SetStatus(nStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RMGfxEngine::InitForNewLocation(int nLoc, RMPoint ptTonyStart, RMPoint start) {
|
|
|
|
if (start.x == -1 || start.y == -1) {
|
2012-05-14 21:29:27 +02:00
|
|
|
start.x = ptTonyStart.x - RM_SX / 2;
|
|
|
|
start.y = ptTonyStart.y - RM_SY / 2;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
m_loc.SetScrollPosition(start);
|
2012-05-14 21:29:27 +02:00
|
|
|
|
|
|
|
if (ptTonyStart.x == 0 && ptTonyStart.y == 0) {
|
2012-05-01 23:00:03 +10:00
|
|
|
} else {
|
2012-05-14 21:29:27 +02:00
|
|
|
m_tony.SetPosition(ptTonyStart, nLoc);
|
2012-05-01 23:00:03 +10:00
|
|
|
m_tony.SetScrollPosition(start);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_curAction = TA_GOTO;
|
|
|
|
m_point.SetCustomPointer(NULL);
|
|
|
|
m_point.SetSpecialPointer(RMPointer::PTR_NONE);
|
|
|
|
m_point.SetAction(m_curAction);
|
|
|
|
m_inter.Reset();
|
|
|
|
m_inv.Reset();
|
|
|
|
|
|
|
|
mpalStartIdlePoll(m_nCurLoc);
|
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
uint32 RMGfxEngine::LoadLocation(int nLoc, RMPoint ptTonyStart, RMPoint start) {
|
2012-05-01 23:00:03 +10:00
|
|
|
bool bLoaded;
|
|
|
|
int i;
|
|
|
|
|
2012-05-14 21:29:27 +02:00
|
|
|
m_nCurLoc = nLoc;
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
bLoaded = false;
|
2012-05-14 21:29:27 +02:00
|
|
|
for (i = 0; i < 5; i++) {
|
2012-05-20 16:34:38 +10:00
|
|
|
// Try the loading of the location
|
2012-05-01 23:00:03 +10:00
|
|
|
RMRes res(m_nCurLoc);
|
|
|
|
if (!res.IsValid())
|
|
|
|
continue;
|
2012-05-20 16:34:38 +10:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
m_loc.Load(res);
|
2012-05-14 21:29:27 +02:00
|
|
|
InitForNewLocation(nLoc, ptTonyStart, start);
|
2012-05-01 23:00:03 +10:00
|
|
|
bLoaded = true;
|
|
|
|
break;
|
|
|
|
}
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
if (!bLoaded)
|
2012-05-20 16:34:38 +10:00
|
|
|
error("Location was not loaded");
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
if (m_bOption)
|
|
|
|
m_opt.ReInit(m_bigBuf);
|
|
|
|
|
|
|
|
m_bLocationLoaded = true;
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// On entering the location
|
2012-05-11 23:15:59 +10:00
|
|
|
return CORO_INVALID_PID_VALUE; //mpalQueryDoAction(0,m_nCurLoc,0);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
void RMGfxEngine::UnloadLocation(CORO_PARAM, bool bDoOnExit, uint32 *result) {
|
2012-05-06 15:18:03 +10:00
|
|
|
CORO_BEGIN_CONTEXT;
|
2012-05-14 21:29:27 +02:00
|
|
|
uint32 h;
|
2012-05-06 15:18:03 +10:00
|
|
|
CORO_END_CONTEXT(_ctx);
|
|
|
|
|
|
|
|
CORO_BEGIN_CODE(_ctx);
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Release the location
|
2012-05-06 15:18:03 +10:00
|
|
|
CORO_INVOKE_2(mpalEndIdlePoll, m_nCurLoc, NULL);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
// On Exit?
|
2012-05-03 23:08:19 +10:00
|
|
|
if (bDoOnExit) {
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->h = mpalQueryDoAction(1, m_nCurLoc, 0);
|
2012-05-11 23:15:59 +10:00
|
|
|
if (_ctx->h != CORO_INVALID_PID_VALUE)
|
|
|
|
CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
MainFreeze();
|
|
|
|
|
|
|
|
m_bLocationLoaded = false;
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bigBuf.ClearOT();
|
|
|
|
m_loc.Unload();
|
|
|
|
|
2012-05-06 15:18:03 +10:00
|
|
|
if (result != NULL)
|
2012-05-11 23:15:59 +10:00
|
|
|
*result = CORO_INVALID_PID_VALUE;
|
2012-05-06 15:18:03 +10:00
|
|
|
|
|
|
|
CORO_END_CODE;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-20 16:34:38 +10:00
|
|
|
void RMGfxEngine::Init() {
|
|
|
|
// Screen loading
|
2012-05-14 21:29:27 +02:00
|
|
|
RMResRaw *raw;
|
2012-05-01 23:00:03 +10:00
|
|
|
RMGfxSourceBuffer16 *load = NULL;
|
|
|
|
INIT_GFX16_FROMRAW(20038, load);
|
|
|
|
m_bigBuf.AddPrim(new RMGfxPrimitive(load));
|
2012-05-12 20:49:36 +10:00
|
|
|
m_bigBuf.DrawOT(Common::nullContext);
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bigBuf.ClearOT();
|
|
|
|
delete load;
|
2012-05-05 20:54:21 +10:00
|
|
|
_vm->_window.GetNewFrame(*this, NULL);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
|
|
|
|
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bPatIrqFreeze = true;
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-20 16:34:38 +10:00
|
|
|
// Activate GUI
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bGUIOption = true;
|
|
|
|
m_bGUIInterface = true;
|
|
|
|
m_bGUIInventory = true;
|
|
|
|
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bSkipSfxNoLoop = false;
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bMustEnterMenu = false;
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bIdleExited = false;
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bOption = false;
|
|
|
|
m_bWiping = false;
|
2012-05-11 23:15:59 +10:00
|
|
|
m_hWipeEvent = CoroScheduler.createEvent(false, false);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Create the freeze event
|
2012-05-04 00:11:38 +10:00
|
|
|
csMainLoop = g_system->createMutex();
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Initialise the IRQ function for items for MPAL
|
2012-05-14 20:20:02 +10:00
|
|
|
GLOBALS.GfxEngine = this;
|
2012-05-01 23:00:03 +10:00
|
|
|
mpalInstallItemIrq(ItemIrq);
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Initialise the input
|
2012-06-05 00:02:15 +02:00
|
|
|
m_input.init();
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Initialise the mouse pointer
|
2012-05-01 23:00:03 +10:00
|
|
|
m_point.Init();
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Initialise Tony
|
2012-05-01 23:00:03 +10:00
|
|
|
m_tony.Init();
|
|
|
|
m_tony.LinkToBoxes(&_vm->_theBoxes);
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Initialise the inventory and the interface
|
2012-05-01 23:00:03 +10:00
|
|
|
m_inv.Init();
|
|
|
|
m_inter.Init();
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Download the location and set priorities @@@@@
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bLocationLoaded = false;
|
2012-05-20 16:34:38 +10:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
EnableInput();
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Starting the game
|
2012-05-14 21:29:27 +02:00
|
|
|
m_tony.ExecuteAction(20, 1, 0);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::Close(void) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bigBuf.ClearOT();
|
|
|
|
|
|
|
|
m_inter.Close();
|
|
|
|
m_inv.Close();
|
|
|
|
m_tony.Close();
|
|
|
|
m_point.Close();
|
2012-06-05 00:02:15 +02:00
|
|
|
m_input.close();
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::SwitchFullscreen(bool bFull) {
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::GDIControl(bool bCon) {
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::EnableInput(void) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bInput = true;
|
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::DisableInput(void) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bInput = false;
|
|
|
|
m_inter.Reset();
|
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::EnableMouse(void) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bAlwaysDrawMouse = true;
|
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::DisableMouse(void) {
|
2012-05-01 23:00:03 +10:00
|
|
|
m_bAlwaysDrawMouse = false;
|
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::Freeze(void) {
|
2012-05-01 23:00:03 +10:00
|
|
|
g_system->lockMutex(csMainLoop);
|
|
|
|
}
|
|
|
|
|
2012-05-03 23:08:19 +10:00
|
|
|
void RMGfxEngine::Unfreeze(void) {
|
2012-05-01 23:00:03 +10:00
|
|
|
g_system->unlockMutex(csMainLoop);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CharsSaveAll(Common::OutSaveFile *f);
|
|
|
|
void CharsLoadAll(Common::InSaveFile *f);
|
|
|
|
void MCharResetCodes(void);
|
|
|
|
void SaveChangedHotspot(Common::OutSaveFile *f);
|
|
|
|
void LoadChangedHotspot(Common::InSaveFile *f);
|
|
|
|
void ReapplyChangedHotspot(void);
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
void RestoreMusic(CORO_PARAM);
|
2012-05-01 23:00:03 +10:00
|
|
|
void SaveMusic(Common::OutSaveFile *f);
|
|
|
|
void LoadMusic(Common::InSaveFile *f);
|
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
#define TONY_SAVEGAME_VERSION 8
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-16 00:05:48 +10:00
|
|
|
void RMGfxEngine::SaveState(const Common::String &fn, byte *curThumb, const Common::String &name) {
|
2012-05-01 23:00:03 +10:00
|
|
|
Common::OutSaveFile *f;
|
2012-05-12 21:54:37 +10:00
|
|
|
byte *state;
|
|
|
|
uint thumbsize;
|
|
|
|
uint size;
|
2012-05-01 23:00:03 +10:00
|
|
|
int i;
|
|
|
|
char buf[4];
|
|
|
|
RMPoint tp = m_tony.Position();
|
|
|
|
|
2012-05-20 15:28:48 +10:00
|
|
|
// Saving: MPAL variables, current location, and Tony inventory position
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// For now, we only save the MPAL state
|
|
|
|
size = mpalGetSaveStateSize();
|
2012-05-01 23:00:03 +10:00
|
|
|
state = new byte[size];
|
|
|
|
mpalSaveState(state);
|
|
|
|
|
|
|
|
thumbsize = 160 * 120 * 2;
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
buf[0] = 'R';
|
|
|
|
buf[1] = 'M';
|
|
|
|
buf[2] = 'S';
|
2012-05-12 21:54:37 +10:00
|
|
|
buf[3] = TONY_SAVEGAME_VERSION;
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
f = g_system->getSavefileManager()->openForSaving(fn);
|
2012-05-14 21:29:27 +02:00
|
|
|
if (f == NULL)
|
2012-05-12 21:54:37 +10:00
|
|
|
return;
|
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
f->write(buf, 4);
|
2012-05-12 21:54:37 +10:00
|
|
|
f->writeUint32LE(thumbsize);
|
|
|
|
f->write(curThumb, thumbsize);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Difficulty level
|
2012-05-01 23:00:03 +10:00
|
|
|
i = mpalQueryGlobalVar("VERSIONEFACILE");
|
|
|
|
f->writeByte(i);
|
|
|
|
|
2012-05-16 00:05:48 +10:00
|
|
|
i = strlen(name.c_str());
|
2012-05-01 23:00:03 +10:00
|
|
|
f->writeByte(i);
|
2012-05-16 00:05:48 +10:00
|
|
|
f->write(name.c_str(), i);
|
2012-05-01 23:00:03 +10:00
|
|
|
f->writeUint32LE(m_nCurLoc);
|
|
|
|
f->writeUint32LE(tp.x);
|
|
|
|
f->writeUint32LE(tp.y);
|
2012-05-12 21:54:37 +10:00
|
|
|
|
2012-05-01 23:00:03 +10:00
|
|
|
f->writeUint32LE(size);
|
2012-05-12 21:54:37 +10:00
|
|
|
f->write(state, size);
|
2012-05-01 23:00:03 +10:00
|
|
|
delete[] state;
|
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Inventory
|
2012-05-01 23:00:03 +10:00
|
|
|
size = m_inv.GetSaveStateSize();
|
|
|
|
state = new byte[size];
|
|
|
|
m_inv.SaveState(state);
|
|
|
|
f->writeUint32LE(size);
|
|
|
|
f->write(state, size);
|
|
|
|
delete[] state;
|
|
|
|
|
|
|
|
// boxes
|
|
|
|
size = _vm->_theBoxes.GetSaveStateSize();
|
|
|
|
state = new byte[size];
|
|
|
|
_vm->_theBoxes.SaveState(state);
|
|
|
|
f->writeUint32LE(size);
|
|
|
|
f->write(state, size);
|
|
|
|
delete[] state;
|
|
|
|
|
|
|
|
// New Ver5
|
|
|
|
bool bStat;
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Saves the state of the shepherdess and show yourself
|
2012-05-01 23:00:03 +10:00
|
|
|
bStat = m_tony.GetPastorella();
|
|
|
|
f->writeByte(bStat);
|
|
|
|
bStat = m_inter.GetPalesati();
|
|
|
|
f->writeByte(bStat);
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Save the chars
|
2012-05-01 23:00:03 +10:00
|
|
|
CharsSaveAll(f);
|
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Save the options
|
2012-05-13 22:34:40 +10:00
|
|
|
f->writeByte(GLOBALS.bCfgInvLocked);
|
|
|
|
f->writeByte(GLOBALS.bCfgInvNoScroll);
|
|
|
|
f->writeByte(GLOBALS.bCfgTimerizedText);
|
|
|
|
f->writeByte(GLOBALS.bCfgInvUp);
|
|
|
|
f->writeByte(GLOBALS.bCfgAnni30);
|
|
|
|
f->writeByte(GLOBALS.bCfgAntiAlias);
|
|
|
|
f->writeByte(GLOBALS.bCfgSottotitoli);
|
|
|
|
f->writeByte(GLOBALS.bCfgTransparence);
|
|
|
|
f->writeByte(GLOBALS.bCfgInterTips);
|
|
|
|
f->writeByte(GLOBALS.bCfgDubbing);
|
|
|
|
f->writeByte(GLOBALS.bCfgMusic);
|
|
|
|
f->writeByte(GLOBALS.bCfgSFX);
|
|
|
|
f->writeByte(GLOBALS.nCfgTonySpeed);
|
|
|
|
f->writeByte(GLOBALS.nCfgTextSpeed);
|
|
|
|
f->writeByte(GLOBALS.nCfgDubbingVolume);
|
|
|
|
f->writeByte(GLOBALS.nCfgMusicVolume);
|
|
|
|
f->writeByte(GLOBALS.nCfgSFXVolume);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Save the hotspots
|
2012-05-01 23:00:03 +10:00
|
|
|
SaveChangedHotspot(f);
|
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Save the music
|
2012-05-01 23:00:03 +10:00
|
|
|
SaveMusic(f);
|
|
|
|
|
|
|
|
f->finalize();
|
|
|
|
delete f;
|
|
|
|
}
|
|
|
|
|
2012-05-16 00:05:48 +10:00
|
|
|
void RMGfxEngine::LoadState(CORO_PARAM, const Common::String &fn) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// PROBLEM: You should change the location in a separate process to do the OnEnter
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_BEGIN_CONTEXT;
|
2012-05-14 21:29:27 +02:00
|
|
|
Common::InSaveFile *f;
|
|
|
|
byte *state, *statecmp;
|
|
|
|
uint size, sizecmp;
|
|
|
|
char buf[4];
|
|
|
|
RMPoint tp;
|
|
|
|
int loc;
|
|
|
|
int ver;
|
|
|
|
int i;
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_END_CONTEXT(_ctx);
|
|
|
|
|
|
|
|
CORO_BEGIN_CODE(_ctx);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->f = g_system->getSavefileManager()->openForLoading(fn);
|
2012-05-14 21:29:27 +02:00
|
|
|
if (_ctx->f == NULL)
|
2012-05-12 21:54:37 +10:00
|
|
|
return;
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->f->read(_ctx->buf, 4);
|
2012-05-12 21:54:37 +10:00
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->buf[0] != 'R' || _ctx->buf[1] != 'M' || _ctx->buf[2] != 'S') {
|
|
|
|
delete _ctx->f;
|
2012-05-01 23:00:03 +10:00
|
|
|
return;
|
|
|
|
}
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->ver = _ctx->buf[3];
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
if (_ctx->ver == 0 || _ctx->ver > TONY_SAVEGAME_VERSION) {
|
2012-05-09 23:15:41 +10:00
|
|
|
delete _ctx->f;
|
2012-05-01 23:00:03 +10:00
|
|
|
return;
|
|
|
|
}
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->ver >= 0x3) {
|
2012-05-12 21:54:37 +10:00
|
|
|
// There is a thumbnail. If the version is between 5 and 7, it's compressed
|
|
|
|
if ((_ctx->ver >= 0x5) && (_ctx->ver <= 0x7)) {
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->i = 0;
|
|
|
|
_ctx->i = _ctx->f->readUint32LE();
|
|
|
|
_ctx->f->seek(_ctx->i);
|
2012-05-12 21:54:37 +10:00
|
|
|
} else {
|
|
|
|
if (_ctx->ver >= 8)
|
|
|
|
// Skip thumbnail size
|
|
|
|
_ctx->f->skip(4);
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->f->seek(160 * 120 * 2, SEEK_CUR);
|
2012-05-12 21:54:37 +10:00
|
|
|
}
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->ver >= 0x5) {
|
2012-05-12 21:54:37 +10:00
|
|
|
// Skip the difficulty level
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->f->seek(1, SEEK_CUR);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-14 21:29:27 +02:00
|
|
|
if (_ctx->ver >= 0x4) { // Skip the savegame name, which serves no purpose
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->i = _ctx->f->readByte();
|
|
|
|
_ctx->f->seek(_ctx->i, SEEK_CUR);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->loc = _ctx->f->readUint32LE();
|
|
|
|
_ctx->tp.x = _ctx->f->readUint32LE();
|
|
|
|
_ctx->tp.y = _ctx->f->readUint32LE();
|
|
|
|
_ctx->size = _ctx->f->readUint32LE();
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
if ((_ctx->ver >= 0x5) && (_ctx->ver <= 7)) {
|
|
|
|
// MPAL was packed!
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->sizecmp = _ctx->f->readUint32LE();
|
|
|
|
_ctx->state = new byte[_ctx->size];
|
|
|
|
_ctx->statecmp = new byte[_ctx->sizecmp];
|
|
|
|
_ctx->f->read(_ctx->statecmp, _ctx->sizecmp);
|
2012-05-14 21:29:27 +02:00
|
|
|
lzo1x_decompress(_ctx->statecmp, _ctx->sizecmp, _ctx->state, &_ctx->size);
|
2012-05-09 23:15:41 +10:00
|
|
|
delete[] _ctx->statecmp;
|
2012-05-01 23:00:03 +10:00
|
|
|
} else {
|
2012-05-12 21:54:37 +10:00
|
|
|
// Read uncompressed MPAL data
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->state = new byte[_ctx->size];
|
|
|
|
_ctx->f->read(_ctx->state, _ctx->size);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
mpalLoadState(_ctx->state);
|
|
|
|
delete[] _ctx->state;
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Inventory
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->size = _ctx->f->readUint32LE();
|
|
|
|
_ctx->state = new byte[_ctx->size];
|
|
|
|
_ctx->f->read(_ctx->state, _ctx->size);
|
|
|
|
m_inv.LoadState(_ctx->state);
|
|
|
|
delete[] _ctx->state;
|
|
|
|
|
2012-05-14 21:29:27 +02:00
|
|
|
if (_ctx->ver >= 0x2) { // Versione 2: box please
|
2012-05-09 23:15:41 +10:00
|
|
|
_ctx->size = _ctx->f->readUint32LE();
|
|
|
|
_ctx->state = new byte[_ctx->size];
|
|
|
|
_ctx->f->read(_ctx->state, _ctx->size);
|
|
|
|
_vm->_theBoxes.LoadState(_ctx->state);
|
|
|
|
delete[] _ctx->state;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->ver >= 5) {
|
2012-05-20 15:28:48 +10:00
|
|
|
// Versione 5
|
2012-05-01 23:00:03 +10:00
|
|
|
bool bStat = false;
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
bStat = _ctx->f->readByte();
|
2012-05-14 21:29:27 +02:00
|
|
|
m_tony.SetPastorella(bStat);
|
2012-05-09 23:15:41 +10:00
|
|
|
bStat = _ctx->f->readByte();
|
2012-05-14 21:29:27 +02:00
|
|
|
m_inter.SetPalesati(bStat);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
CharsLoadAll(_ctx->f);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->ver >= 6) {
|
2012-05-12 21:54:37 +10:00
|
|
|
// Load options
|
2012-05-13 22:34:40 +10:00
|
|
|
GLOBALS.bCfgInvLocked = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgInvNoScroll = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgTimerizedText = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgInvUp = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgAnni30 = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgAntiAlias = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgSottotitoli = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgTransparence = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgInterTips = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgDubbing = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgMusic = _ctx->f->readByte();
|
|
|
|
GLOBALS.bCfgSFX = _ctx->f->readByte();
|
|
|
|
GLOBALS.nCfgTonySpeed = _ctx->f->readByte();
|
|
|
|
GLOBALS.nCfgTextSpeed = _ctx->f->readByte();
|
|
|
|
GLOBALS.nCfgDubbingVolume = _ctx->f->readByte();
|
|
|
|
GLOBALS.nCfgMusicVolume = _ctx->f->readByte();
|
|
|
|
GLOBALS.nCfgSFXVolume = _ctx->f->readByte();
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// Load hotspots
|
2012-05-09 23:15:41 +10:00
|
|
|
LoadChangedHotspot(_ctx->f);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->ver >= 7) {
|
|
|
|
LoadMusic(_ctx->f);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
delete _ctx->f;
|
2012-05-01 23:00:03 +10:00
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_INVOKE_2(UnloadLocation, false, NULL);
|
2012-05-14 21:29:27 +02:00
|
|
|
LoadLocation(_ctx->loc, _ctx->tp, RMPoint(-1, -1));
|
2012-05-01 23:00:03 +10:00
|
|
|
m_tony.SetPattern(RMTony::PAT_STANDRIGHT);
|
|
|
|
MainUnfreeze();
|
2012-05-14 21:29:27 +02:00
|
|
|
|
2012-05-12 21:54:37 +10:00
|
|
|
// On older versions, need to an enter action
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->ver < 5)
|
|
|
|
mpalQueryDoAction(0, _ctx->loc, 0);
|
2012-05-01 23:00:03 +10:00
|
|
|
else {
|
2012-05-12 21:54:37 +10:00
|
|
|
// In the new ones, we just reset the mcode
|
2012-05-01 23:00:03 +10:00
|
|
|
MCharResetCodes();
|
|
|
|
}
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
if (_ctx->ver >= 6)
|
2012-05-01 23:00:03 +10:00
|
|
|
ReapplyChangedHotspot();
|
|
|
|
|
2012-05-09 23:15:41 +10:00
|
|
|
CORO_INVOKE_0(RestoreMusic);
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
m_bGUIInterface = true;
|
|
|
|
m_bGUIInventory = true;
|
|
|
|
m_bGUIOption = true;
|
2012-05-09 23:15:41 +10:00
|
|
|
|
|
|
|
CORO_END_CODE;
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void RMGfxEngine::PauseSound(bool bPause) {
|
|
|
|
if (m_bLocationLoaded)
|
|
|
|
m_loc.PauseSound(bPause);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RMGfxEngine::InitWipe(int type) {
|
|
|
|
m_bWiping = true;
|
2012-05-14 21:29:27 +02:00
|
|
|
m_nWipeType = type;
|
|
|
|
m_nWipeStep = 0;
|
2012-05-01 23:00:03 +10:00
|
|
|
|
|
|
|
if (m_nWipeType == 1)
|
|
|
|
m_rcWipeEllipse = Common::Rect(80, 0, 640 - 80, 480);
|
|
|
|
else if (m_nWipeType == 2)
|
|
|
|
m_rcWipeEllipse = Common::Rect(320 - FSTEP, 240 - FSTEP, 320 + FSTEP, 240 + FSTEP);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RMGfxEngine::CloseWipe(void) {
|
|
|
|
m_bWiping = false;
|
|
|
|
}
|
|
|
|
|
2012-05-09 00:42:27 +10:00
|
|
|
void RMGfxEngine::WaitWipeEnd(CORO_PARAM) {
|
2012-05-11 23:15:59 +10:00
|
|
|
CoroScheduler.waitForSingleObject(coroParam, m_hWipeEvent, CORO_INFINITE);
|
2012-05-01 23:00:03 +10:00
|
|
|
}
|
2012-04-30 09:27:12 +10:00
|
|
|
|
2012-05-16 00:05:48 +10:00
|
|
|
bool RMGfxEngine::CanLoadSave() {
|
2012-05-17 19:41:53 +10:00
|
|
|
return m_bInput && !m_tony.InAction() && !_vm->getIsDemo();
|
2012-05-16 00:05:48 +10:00
|
|
|
}
|
|
|
|
|
2012-04-30 09:27:12 +10:00
|
|
|
} // End of namespace Tony
|