mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
TONY: Beginnings of refactoring Tony engine's threads to use coroutines
This commit is contained in:
parent
2dbdb31c8b
commit
10deebed55
82
engines/tony/coroutine.cpp
Normal file
82
engines/tony/coroutine.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "tony/coroutine.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/hash-str.h"
|
||||
|
||||
namespace Tony {
|
||||
|
||||
|
||||
CoroContext nullContext = NULL; // FIXME: Avoid non-const global vars
|
||||
|
||||
|
||||
#if COROUTINE_DEBUG
|
||||
namespace {
|
||||
static int s_coroCount = 0;
|
||||
|
||||
typedef Common::HashMap<Common::String, int> CoroHashMap;
|
||||
static CoroHashMap *s_coroFuncs = 0;
|
||||
|
||||
static void changeCoroStats(const char *func, int change) {
|
||||
if (!s_coroFuncs)
|
||||
s_coroFuncs = new CoroHashMap();
|
||||
|
||||
(*s_coroFuncs)[func] += change;
|
||||
}
|
||||
|
||||
static void displayCoroStats() {
|
||||
debug("%d active coros", s_coroCount);
|
||||
|
||||
// Loop over s_coroFuncs and print info about active coros
|
||||
if (!s_coroFuncs)
|
||||
return;
|
||||
for (CoroHashMap::const_iterator it = s_coroFuncs->begin();
|
||||
it != s_coroFuncs->end(); ++it) {
|
||||
if (it->_value != 0)
|
||||
debug(" %3d x %s", it->_value, it->_key.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
CoroBaseContext::CoroBaseContext(const char *func)
|
||||
: _line(0), _sleep(0), _subctx(0) {
|
||||
#if COROUTINE_DEBUG
|
||||
_funcName = func;
|
||||
changeCoroStats(_funcName, +1);
|
||||
s_coroCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
CoroBaseContext::~CoroBaseContext() {
|
||||
#if COROUTINE_DEBUG
|
||||
s_coroCount--;
|
||||
changeCoroStats(_funcName, -1);
|
||||
debug("Deleting coro in %s at %p (subctx %p)",
|
||||
_funcName, (void *)this, (void *)_subctx);
|
||||
displayCoroStats();
|
||||
#endif
|
||||
delete _subctx;
|
||||
}
|
||||
|
||||
} // End of namespace Tony
|
271
engines/tony/coroutine.h
Normal file
271
engines/tony/coroutine.h
Normal file
@ -0,0 +1,271 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TONY_COROUTINE_H
|
||||
#define TONY_COROUTINE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h" // for SCUMMVM_CURRENT_FUNCTION
|
||||
|
||||
namespace Tony {
|
||||
|
||||
/**
|
||||
* @defgroup TonyCoroutines Coroutine support for Tony engine
|
||||
*
|
||||
* The following is loosely based on an article by Simon Tatham:
|
||||
* <http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html>.
|
||||
* However, many improvements and tweaks have been made, in particular
|
||||
* by taking advantage of C++ features not available in C.
|
||||
*/
|
||||
//@{
|
||||
|
||||
|
||||
// Enable this macro to enable some debugging support in the coroutine code.
|
||||
//#define COROUTINE_DEBUG 1
|
||||
|
||||
/**
|
||||
* The core of any coroutine context which captures the 'state' of a coroutine.
|
||||
* Private use only.
|
||||
*/
|
||||
struct CoroBaseContext {
|
||||
int _line;
|
||||
int _sleep;
|
||||
CoroBaseContext *_subctx;
|
||||
#if COROUTINE_DEBUG
|
||||
const char *_funcName;
|
||||
#endif
|
||||
CoroBaseContext(const char *func);
|
||||
~CoroBaseContext();
|
||||
};
|
||||
|
||||
typedef CoroBaseContext *CoroContext;
|
||||
|
||||
|
||||
// FIXME: Document this!
|
||||
extern CoroContext nullContext;
|
||||
|
||||
/**
|
||||
* Wrapper class which holds a pointer to a pointer to a CoroBaseContext.
|
||||
* The interesting part is the destructor, which kills the context being held,
|
||||
* but ONLY if the _sleep val of that context is zero. This way, a coroutine
|
||||
* can just 'return' w/o having to worry about freeing the allocated context
|
||||
* (in Simon Tatham's original code, one had to use a special macro to
|
||||
* return from a coroutine).
|
||||
*/
|
||||
class CoroContextHolder {
|
||||
CoroContext &_ctx;
|
||||
public:
|
||||
CoroContextHolder(CoroContext &ctx) : _ctx(ctx) {
|
||||
assert(ctx);
|
||||
assert(ctx->_sleep >= 0);
|
||||
ctx->_sleep = 0;
|
||||
}
|
||||
~CoroContextHolder() {
|
||||
if (_ctx && _ctx->_sleep == 0) {
|
||||
delete _ctx;
|
||||
_ctx = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define CORO_PARAM CoroContext &coroParam
|
||||
|
||||
|
||||
/**
|
||||
* Begin the declaration of a coroutine context.
|
||||
* This allows declaring variables which are 'persistent' during the
|
||||
* lifetime of the coroutine. An example use would be:
|
||||
*
|
||||
* CORO_BEGIN_CONTEXT;
|
||||
* int var;
|
||||
* char *foo;
|
||||
* CORO_END_CONTEXT(_ctx);
|
||||
*
|
||||
* It is not possible to initialize variables here, due to the way this
|
||||
* macro is implemented. Furthermore, to use the variables declared in
|
||||
* the coroutine context, you have to access them via the context variable
|
||||
* name that was specified as parameter to CORO_END_CONTEXT, e.g.
|
||||
* _ctx->var = 0;
|
||||
*
|
||||
* @see CORO_END_CONTEXT
|
||||
*
|
||||
* @note We declare a variable 'DUMMY' to allow the user to specify an 'empty'
|
||||
* context, and so compilers won't complain about ";" following the macro.
|
||||
*/
|
||||
#define CORO_BEGIN_CONTEXT \
|
||||
struct CoroContextTag : CoroBaseContext { \
|
||||
CoroContextTag() : CoroBaseContext(SCUMMVM_CURRENT_FUNCTION) {} \
|
||||
int DUMMY
|
||||
|
||||
/**
|
||||
* End the declaration of a coroutine context.
|
||||
* @param x name of the coroutine context
|
||||
* @see CORO_BEGIN_CONTEXT
|
||||
*/
|
||||
#define CORO_END_CONTEXT(x) } *x = (CoroContextTag *)coroParam
|
||||
|
||||
/**
|
||||
* Begin the code section of a coroutine.
|
||||
* @param x name of the coroutine context
|
||||
* @see CORO_BEGIN_CODE
|
||||
*/
|
||||
#define CORO_BEGIN_CODE(x) \
|
||||
if (&coroParam == &nullContext) assert(!nullContext);\
|
||||
if (!x) {coroParam = x = new CoroContextTag();}\
|
||||
CoroContextHolder tmpHolder(coroParam);\
|
||||
switch (coroParam->_line) { case 0:;
|
||||
|
||||
/**
|
||||
* End the code section of a coroutine.
|
||||
* @see CORO_END_CODE
|
||||
*/
|
||||
#define CORO_END_CODE \
|
||||
if (&coroParam == &nullContext) { \
|
||||
delete nullContext; \
|
||||
nullContext = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep for the specified number of scheduler cycles.
|
||||
*/
|
||||
#define CORO_SLEEP(delay) do {\
|
||||
coroParam->_line = __LINE__;\
|
||||
coroParam->_sleep = delay;\
|
||||
assert(&coroParam != &nullContext);\
|
||||
return; case __LINE__:;\
|
||||
} while (0)
|
||||
|
||||
#define CORO_GIVE_WAY do { g_scheduler->giveWay(); CORO_SLEEP(1); } while (0)
|
||||
#define CORO_RESCHEDULE do { g_scheduler->reschedule(); CORO_SLEEP(1); } while (0)
|
||||
|
||||
/**
|
||||
* Stop the currently running coroutine and all calling coroutines.
|
||||
*
|
||||
* This sets _sleep to -1 rather than 0 so that the context doesn't get
|
||||
* deleted by CoroContextHolder, since we want CORO_INVOKE_ARGS to
|
||||
* propogate the _sleep value and return immediately (the scheduler will
|
||||
* then delete the entire coroutine's state, including all subcontexts).
|
||||
*/
|
||||
#define CORO_KILL_SELF() \
|
||||
do { if (&coroParam != &nullContext) { coroParam->_sleep = -1; } return; } while (0)
|
||||
|
||||
|
||||
/**
|
||||
* This macro is to be used in conjunction with CORO_INVOKE_ARGS and
|
||||
* similar macros for calling coroutines-enabled subroutines.
|
||||
*/
|
||||
#define CORO_SUBCTX coroParam->_subctx
|
||||
|
||||
/**
|
||||
* Invoke another coroutine.
|
||||
*
|
||||
* If the subcontext still exists after the coroutine is invoked, it has
|
||||
* either yielded/slept or killed itself, and so we copy the _sleep value
|
||||
* to our own context and return (execution will continue at the case
|
||||
* statement below, where we loop and call the coroutine again).
|
||||
* If the subcontext is null, the coroutine ended normally, and we can
|
||||
* simply break out of the loop and continue execution.
|
||||
*
|
||||
* @param subCoro name of the coroutine-enabled function to invoke
|
||||
* @param ARGS list of arguments to pass to subCoro
|
||||
*
|
||||
* @note ARGS must be surrounded by parentheses, and the first argument
|
||||
* in this list must always be CORO_SUBCTX. For example, the
|
||||
* regular function call
|
||||
* myFunc(a, b);
|
||||
* becomes the following:
|
||||
* CORO_INVOKE_ARGS(myFunc, (CORO_SUBCTX, a, b));
|
||||
*/
|
||||
#define CORO_INVOKE_ARGS(subCoro, ARGS) \
|
||||
do {\
|
||||
coroParam->_line = __LINE__;\
|
||||
coroParam->_subctx = 0;\
|
||||
do {\
|
||||
subCoro ARGS;\
|
||||
if (!coroParam->_subctx) break;\
|
||||
coroParam->_sleep = coroParam->_subctx->_sleep;\
|
||||
assert(&coroParam != &nullContext);\
|
||||
return; case __LINE__:;\
|
||||
} while (1);\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Invoke another coroutine. Similar to CORO_INVOKE_ARGS,
|
||||
* but allows specifying a return value which is returned
|
||||
* if invoked coroutine yields (thus causing the current
|
||||
* coroutine to yield, too).
|
||||
*/
|
||||
#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \
|
||||
do {\
|
||||
coroParam->_line = __LINE__;\
|
||||
coroParam->_subctx = 0;\
|
||||
do {\
|
||||
subCoro ARGS;\
|
||||
if (!coroParam->_subctx) break;\
|
||||
coroParam->_sleep = coroParam->_subctx->_sleep;\
|
||||
assert(&coroParam != &nullContext);\
|
||||
return RESULT; case __LINE__:;\
|
||||
} while (1);\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
|
||||
* with no parameters.
|
||||
*/
|
||||
#define CORO_INVOKE_0(subCoroutine) \
|
||||
CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX))
|
||||
|
||||
/**
|
||||
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
|
||||
* with one parameter.
|
||||
*/
|
||||
#define CORO_INVOKE_1(subCoroutine, a0) \
|
||||
CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0))
|
||||
|
||||
/**
|
||||
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
|
||||
* with two parameters.
|
||||
*/
|
||||
#define CORO_INVOKE_2(subCoroutine, a0,a1) \
|
||||
CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1))
|
||||
|
||||
/**
|
||||
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
|
||||
* with three parameters.
|
||||
*/
|
||||
#define CORO_INVOKE_3(subCoroutine, a0,a1,a2) \
|
||||
CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2))
|
||||
|
||||
/**
|
||||
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
|
||||
* with four parameters.
|
||||
*/
|
||||
#define CORO_INVOKE_4(subCoroutine, a0,a1,a2,a3) \
|
||||
CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2,a3))
|
||||
|
||||
//@}
|
||||
|
||||
} // End of namespace Tony
|
||||
|
||||
#endif // TONY_COROUTINE_H
|
@ -297,38 +297,38 @@ void CharsLoadAll(Common::InSaveFile *f) {
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(FaceToMe)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(FaceToMe)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->SetPattern(Tony->PAT_STANDDOWN);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(BackToMe)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(BackToMe)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->SetPattern(Tony->PAT_STANDUP);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(LeftToMe)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(LeftToMe)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->SetPattern(Tony->PAT_STANDLEFT);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(RightToMe)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(RightToMe)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->SetPattern(Tony->PAT_STANDRIGHT);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySetPalesati)(uint32 bStatus, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySetPalesati)(CORO_PARAM, uint32 bStatus, uint32, uint32, uint32) {
|
||||
SetPalesati(bStatus);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MySleep)(uint32 dwTime, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MySleep)(CORO_PARAM, uint32 dwTime, uint32, uint32, uint32) {
|
||||
if (bSkipIdle) return;
|
||||
Sleep(dwTime);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SetAlwaysDisplay)(uint32 val, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SetAlwaysDisplay)(CORO_PARAM, uint32 val, uint32, uint32, uint32) {
|
||||
bAlwaysDisplay = (val != 0);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SetPointer)(uint32 dwPointer, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SetPointer)(CORO_PARAM, uint32 dwPointer, uint32, uint32, uint32) {
|
||||
switch (dwPointer) {
|
||||
case 1:
|
||||
Pointer->SetSpecialPointer(Pointer->PTR_FRECCIASU);
|
||||
@ -369,7 +369,7 @@ VoiceHeader *SearchVoiceHeader(uint32 codehi, uint32 codelo) {
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(uint32 dwMessage, uint32 nX, uint32 nY, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX, uint32 nY, uint32) {
|
||||
RMMessage msg(dwMessage);
|
||||
int i;
|
||||
int curOffset = 0;
|
||||
@ -476,12 +476,12 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(uint32 dwMessage, uint32 nX, uint32 nY,
|
||||
Tony->EndTalk();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeBoxStatus)(uint32 nLoc, uint32 nBox, uint32 nStatus, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeBoxStatus)(CORO_PARAM, uint32 nLoc, uint32 nBox, uint32 nStatus, uint32) {
|
||||
Boxes->ChangeBoxStatus(nLoc,nBox,nStatus);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CustLoadLocation)(uint32 nLoc, uint32 tX, uint32 tY, uint32 bUseStartPos) {
|
||||
DECLARE_CUSTOM_FUNCTION(CustLoadLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, uint32 tY, uint32 bUseStartPos) {
|
||||
HANDLE h;
|
||||
|
||||
Freeze();
|
||||
@ -504,7 +504,7 @@ DECLARE_CUSTOM_FUNCTION(CustLoadLocation)(uint32 nLoc, uint32 tX, uint32 tY, uin
|
||||
RMPoint SFM_pt;
|
||||
int SFM_nLoc;
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgStart)(uint32 nMsg, uint32 nFont, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgStart)(CORO_PARAM, uint32 nMsg, uint32 nFont, uint32, uint32) {
|
||||
RMMessage msg(nMsg);
|
||||
RMGfxClearTask clear;
|
||||
int i;
|
||||
@ -554,14 +554,14 @@ DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgStart)(uint32 nMsg, uint32 nFont, uint3
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(ClearScreen)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(ClearScreen)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
RMGfxClearTask clear;
|
||||
|
||||
LinkGraphicTask(&clear);
|
||||
WaitFrame();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgEnd)(uint32 bNotEnableTony, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgEnd)(CORO_PARAM, uint32 bNotEnableTony, uint32, uint32, uint32) {
|
||||
Freeze();
|
||||
LoadLocation(SFM_nLoc,RMPoint(SFM_pt.x,SFM_pt.y),RMPoint(-1,-1));
|
||||
if (!bNotEnableTony)
|
||||
@ -573,18 +573,25 @@ DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgEnd)(uint32 bNotEnableTony, uint32, uin
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SendFullscreenMessage)(uint32 nMsg, uint32 nFont, uint32, uint32) {
|
||||
SendFullscreenMsgStart(nMsg,nFont,0,0);
|
||||
SendFullscreenMsgEnd(0, 0, 0, 0);
|
||||
DECLARE_CUSTOM_FUNCTION(SendFullscreenMessage)(CORO_PARAM, uint32 nMsg, uint32 nFont, uint32, uint32) {
|
||||
CORO_BEGIN_CONTEXT;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
CORO_INVOKE_4(SendFullscreenMsgStart, nMsg, nFont, 0, 0);
|
||||
CORO_INVOKE_4(SendFullscreenMsgEnd, 0, 0, 0, 0);
|
||||
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
bool bNoOcchioDiBue = false;
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(NoOcchioDiBue)(uint32, uint32, uint32, uint32) {
|
||||
bNoOcchioDiBue = true;
|
||||
DECLARE_CUSTOM_FUNCTION(NoOcchioDiBue)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
bNoOcchioDiBue = true;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CloseLocation)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(CloseLocation)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
if (!bNoOcchioDiBue) {
|
||||
InitWipe(1);
|
||||
WaitWipeEnd();
|
||||
@ -598,7 +605,7 @@ DECLARE_CUSTOM_FUNCTION(CloseLocation)(uint32, uint32, uint32, uint32) {
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeLocation)(uint32 nLoc, uint32 tX, uint32 tY, uint32 bUseStartPos) {
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, uint32 tY, uint32 bUseStartPos) {
|
||||
HANDLE h;
|
||||
|
||||
if (!bNoOcchioDiBue) {
|
||||
@ -647,40 +654,48 @@ DECLARE_CUSTOM_FUNCTION(ChangeLocation)(uint32 nLoc, uint32 tX, uint32 tY, uint3
|
||||
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SetLocStartPosition)(uint32 nLoc, uint32 lX, uint32 lY, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SetLocStartPosition)(CORO_PARAM, uint32 nLoc, uint32 lX, uint32 lY, uint32) {
|
||||
StartLocPos[nLoc].Set(lX,lY);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SaveTonyPosition)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SaveTonyPosition)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
saveTonyPos = Tony->Position();
|
||||
saveTonyLoc = Loc->TEMPGetNumLoc();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(RestoreTonyPosition)(uint32, uint32, uint32, uint32) {
|
||||
ChangeLocation(saveTonyLoc, saveTonyPos.x, saveTonyPos.y, 0);
|
||||
DECLARE_CUSTOM_FUNCTION(RestoreTonyPosition)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
CORO_BEGIN_CONTEXT;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
CORO_INVOKE_4(ChangeLocation, saveTonyLoc, saveTonyPos.x, saveTonyPos.y, 0);
|
||||
|
||||
MCharResetCodes();
|
||||
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(DisableInput)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(DisableInput)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
MainDisableInput();
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(EnableInput)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(EnableInput)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
MainEnableInput();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(StopTony)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(StopTony)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->StopNoAction();
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CustEnableGUI)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(CustEnableGUI)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
EnableGUI();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CustDisableGUI)(uint32, uint32, uint32, uint32)
|
||||
DECLARE_CUSTOM_FUNCTION(CustDisableGUI)(CORO_PARAM, uint32, uint32, uint32, uint32)
|
||||
{
|
||||
DisableGUI();
|
||||
}
|
||||
@ -731,31 +746,31 @@ void TonyGenericPut2(uint32 nDirection) {
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeUp1)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeUp1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericTake1(0);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeMid1)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeMid1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericTake1(1);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeDown1)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeDown1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericTake1(2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeUp2)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeUp2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericTake2(0);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeMid2)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeMid2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericTake2(1);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeDown2)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyTakeDown2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericTake2(2);
|
||||
}
|
||||
|
||||
@ -765,42 +780,42 @@ DECLARE_CUSTOM_FUNCTION(TonyTakeDown2)(uint32, uint32, uint32, uint32) {
|
||||
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutUp1)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutUp1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericPut1(0);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutMid1)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutMid1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericPut1(1);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutDown1)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutDown1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericPut1(2);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutUp2)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutUp2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericPut2(0);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutMid2)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutMid2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericPut2(1);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutDown2)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPutDown2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
TonyGenericPut2(2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPerTerra)(uint32 dwParte, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPerTerra)(CORO_PARAM, uint32 dwParte, uint32, uint32, uint32) {
|
||||
if (dwParte== 0)
|
||||
Tony->SetPattern(Tony->PAT_PERTERRALEFT);
|
||||
else
|
||||
Tony->SetPattern(Tony->PAT_PERTERRARIGHT);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySiRialza)(uint32 dwParte, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySiRialza)(CORO_PARAM, uint32 dwParte, uint32, uint32, uint32) {
|
||||
if (dwParte== 0)
|
||||
Tony->SetPattern(Tony->PAT_SIRIALZALEFT);
|
||||
else
|
||||
@ -810,11 +825,11 @@ DECLARE_CUSTOM_FUNCTION(TonySiRialza)(uint32 dwParte, uint32, uint32, uint32) {
|
||||
Tony->WaitForEndPattern();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPastorella)(uint32 bIsPast, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyPastorella)(CORO_PARAM, uint32 bIsPast, uint32, uint32, uint32) {
|
||||
Tony->SetPastorella(bIsPast);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyFischietto)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyFischietto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->SetPattern(Tony->PAT_FISCHIETTORIGHT);
|
||||
if (!bSkipIdle)
|
||||
Tony->WaitForEndPattern();
|
||||
@ -827,182 +842,182 @@ void TonySetNumTexts(uint32 dwText) {
|
||||
bTonyInTexts = false;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyRide)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyRide)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_RIDE;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyRidacchia)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyRidacchia)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_RIDE2;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyFianchi)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyFianchi)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_FIANCHI;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyCanta)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyCanta)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CANTA;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySiIndica)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySiIndica)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_SIINDICA;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoConMani)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoConMani)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_SPAVENTATO;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoSenzaMani)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoSenzaMani)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_SPAVENTATO2;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConMartello)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConMartello)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONMARTELLO;
|
||||
Tony->SetPattern(Tony->PAT_CONMARTELLO);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConBicchiere)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConBicchiere)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONBICCHIERE;
|
||||
Tony->SetPattern(Tony->PAT_CONBICCHIERE);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConVerme)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConVerme)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONVERME;
|
||||
Tony->SetPattern(Tony->PAT_CONVERME);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCorda)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCorda)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONCORDA;
|
||||
Tony->SetPattern(Tony->PAT_CONCORDA);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConSegretaria)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConSegretaria)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONSEGRETARIA;
|
||||
Tony->SetPattern(Tony->PAT_CONSEGRETARIA);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConConiglioANIM)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConConiglioANIM)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONCONIGLIO;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConRicettaANIM)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConRicettaANIM)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONRICETTA;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCarteANIM)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCarteANIM)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONCARTE;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoANIM)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoANIM)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_CONPUPAZZO;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_CONPUPAZZOSTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_CONPUPAZZOSTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_CONPUPAZZOSTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConConiglioStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConConiglioStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_CONCONIGLIOSTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_CONCONIGLIOSTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConConiglioEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConConiglioEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_CONCONIGLIOSTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConRicettaStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConRicettaStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_CONRICETTASTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_CONRICETTASTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConRicettaEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConRicettaEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_CONRICETTASTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCarteStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCarteStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_CONCARTESTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_CONCARTESTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCarteEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConCarteEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_CONCARTESTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConTaccuinoStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConTaccuinoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_CONTACCUINOSTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_CONTACCUINOSTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConTaccuinoEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConTaccuinoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_CONTACCUINOSTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConMegafonoStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConMegafonoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_CONMEGAFONOSTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_CONMEGAFONOSTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConMegafonoEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConMegafonoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_CONMEGAFONOSTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConBarbaStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConBarbaStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_CONBARBASTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_CONBARBASTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConBarbaEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyConBarbaEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_CONBARBASTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
nTonyNextTalkType = Tony->TALK_SPAVENTATOSTATIC;
|
||||
bStaticTalk = true;
|
||||
Tony->StartStatic(Tony->TALK_SPAVENTATOSTATIC);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySpaventatoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->EndStatic(Tony->TALK_SPAVENTATOSTATIC);
|
||||
bStaticTalk = false;
|
||||
nTonyNextTalkType = Tony->TALK_NORMAL;
|
||||
@ -1010,29 +1025,43 @@ DECLARE_CUSTOM_FUNCTION(TonySpaventatoEnd)(uint32, uint32, uint32, uint32) {
|
||||
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySchifato)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySchifato)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_SCHIFATO;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySniffaLeft)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySniffaLeft)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
CORO_BEGIN_CONTEXT;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
Tony->SetPattern(Tony->PAT_SNIFFA_LEFT);
|
||||
Tony->WaitForEndPattern();
|
||||
LeftToMe(0, 0, 0, 0);
|
||||
CORO_INVOKE_4(LeftToMe, 0, 0, 0, 0);
|
||||
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonySniffaRight)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonySniffaRight)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
CORO_BEGIN_CONTEXT;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
Tony->SetPattern(Tony->PAT_SNIFFA_RIGHT);
|
||||
Tony->WaitForEndPattern();
|
||||
RightToMe(0, 0, 0, 0);
|
||||
CORO_INVOKE_4(RightToMe, 0, 0, 0, 0);
|
||||
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyNaah)(uint32 dwText, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyNaah)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
|
||||
TonySetNumTexts(dwText);
|
||||
nTonyNextTalkType = Tony->TALK_NAAH;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TonyMacbeth)(uint32 nPos, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TonyMacbeth)(CORO_PARAM, uint32 nPos, uint32, uint32, uint32) {
|
||||
switch (nPos) {
|
||||
case 1:
|
||||
nTonyNextTalkType = Tony->TALK_MACBETH1;
|
||||
@ -1065,15 +1094,15 @@ DECLARE_CUSTOM_FUNCTION(TonyMacbeth)(uint32 nPos, uint32, uint32, uint32) {
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(EnableTony)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(EnableTony)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Tony->Show();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(DisableTony)(uint32 bShowOmbra, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(DisableTony)(CORO_PARAM, uint32 bShowOmbra, uint32, uint32, uint32) {
|
||||
Tony->Hide(bShowOmbra);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(WaitForPatternEnd)(uint32 nItem, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(WaitForPatternEnd)(CORO_PARAM, uint32 nItem, uint32, uint32, uint32) {
|
||||
RMItem *item = Loc->GetItemFromCode(nItem);
|
||||
|
||||
if (!bSkipIdle && item != NULL)
|
||||
@ -1081,22 +1110,22 @@ DECLARE_CUSTOM_FUNCTION(WaitForPatternEnd)(uint32 nItem, uint32, uint32, uint32)
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SetTonyPosition)(uint32 nX, uint32 nY, uint32 nLoc, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SetTonyPosition)(CORO_PARAM, uint32 nX, uint32 nY, uint32 nLoc, uint32) {
|
||||
Tony->SetPosition(RMPoint(nX, nY), nLoc);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MoveTonyAndWait)(uint32 nX, uint32 nY, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MoveTonyAndWait)(CORO_PARAM, uint32 nX, uint32 nY, uint32, uint32) {
|
||||
Tony->Move(RMPoint(nX, nY));
|
||||
|
||||
if (!bSkipIdle)
|
||||
Tony->WaitForEndMovement();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MoveTony)(uint32 nX, uint32 nY, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MoveTony)(CORO_PARAM, uint32 nX, uint32 nY, uint32, uint32) {
|
||||
Tony->Move(RMPoint(nX, nY));
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(ScrollLocation)(uint32 nX, uint32 nY, uint32 sX, uint32 sY) {
|
||||
DECLARE_CUSTOM_FUNCTION(ScrollLocation)(CORO_PARAM, uint32 nX, uint32 nY, uint32 sX, uint32 sY) {
|
||||
int lx, ly;
|
||||
RMPoint pt;
|
||||
|
||||
@ -1133,7 +1162,7 @@ DECLARE_CUSTOM_FUNCTION(ScrollLocation)(uint32 nX, uint32 nY, uint32 sX, uint32
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SyncScrollLocation)(uint32 nX, uint32 nY, uint32 sX, uint32 sY) {
|
||||
DECLARE_CUSTOM_FUNCTION(SyncScrollLocation)(CORO_PARAM, uint32 nX, uint32 nY, uint32 sX, uint32 sY) {
|
||||
int lx, ly;
|
||||
RMPoint pt, startpt;
|
||||
uint32 dwStartTime, dwCurTime, dwTotalTime;
|
||||
@ -1231,7 +1260,7 @@ DECLARE_CUSTOM_FUNCTION(SyncScrollLocation)(uint32 nX, uint32 nY, uint32 sX, uin
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeHotspot)(uint32 dwCode, uint32 nX, uint32 nY, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeHotspot)(CORO_PARAM, uint32 dwCode, uint32 nX, uint32 nY, uint32) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < curChangedHotspot; i++)
|
||||
@ -1252,15 +1281,15 @@ DECLARE_CUSTOM_FUNCTION(ChangeHotspot)(uint32 dwCode, uint32 nX, uint32 nY, uint
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(AutoSave)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(AutoSave)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_vm->AutoSave();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(Abort)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(Abort)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_vm->Abort();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TremaSchermo)(uint32 nScosse, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TremaSchermo)(CORO_PARAM, uint32 nScosse, uint32, uint32, uint32) {
|
||||
uint32 i;
|
||||
uint32 curTime = _vm->GetTime();
|
||||
int dirx,diry;
|
||||
@ -1296,7 +1325,7 @@ DECLARE_CUSTOM_FUNCTION(TremaSchermo)(uint32 nScosse, uint32, uint32, uint32) {
|
||||
* Personaggi
|
||||
*/
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetCode)(uint32 nChar, uint32 nCode, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetCode)(CORO_PARAM, uint32 nChar, uint32 nCode, uint32, uint32) {
|
||||
assert(nChar < 16);
|
||||
Character[nChar].code = nCode;
|
||||
Character[nChar].item = Loc->GetItemFromCode(nCode);
|
||||
@ -1311,26 +1340,26 @@ DECLARE_CUSTOM_FUNCTION(CharSetCode)(uint32 nChar, uint32 nCode, uint32, uint32)
|
||||
IsMChar[nChar] = false;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetColor)(uint32 nChar, uint32 r, uint32 g, uint32 b) {
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetColor)(CORO_PARAM, uint32 nChar, uint32 r, uint32 g, uint32 b) {
|
||||
assert(nChar<16);
|
||||
Character[nChar].r = r;
|
||||
Character[nChar].g = g;
|
||||
Character[nChar].b = b;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetTalkPattern)(uint32 nChar, uint32 tp, uint32 sp, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetTalkPattern)(CORO_PARAM, uint32 nChar, uint32 tp, uint32 sp, uint32) {
|
||||
assert(nChar<16);
|
||||
Character[nChar].talkpattern = tp;
|
||||
Character[nChar].standpattern = sp;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetStartEndTalkPattern)(uint32 nChar, uint32 sp, uint32 ep, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(CharSetStartEndTalkPattern)(CORO_PARAM, uint32 nChar, uint32 sp, uint32 ep, uint32) {
|
||||
assert(nChar<16);
|
||||
Character[nChar].starttalkpattern=sp;
|
||||
Character[nChar].endtalkpattern=ep;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(CharSendMessage)(uint32 nChar, uint32 dwMessage, uint32 bIsBack, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(CharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMessage, uint32 bIsBack, uint32) {
|
||||
RMMessage msg(dwMessage);
|
||||
int i;
|
||||
RMPoint pt;
|
||||
@ -1433,15 +1462,15 @@ DECLARE_CUSTOM_FUNCTION(CharSendMessage)(uint32 nChar, uint32 dwMessage, uint32
|
||||
Unfreeze();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(AddInventory)(uint32 dwCode, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(AddInventory)(CORO_PARAM, uint32 dwCode, uint32, uint32, uint32) {
|
||||
Inventory->AddItem(dwCode);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(RemoveInventory)(uint32 dwCode, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(RemoveInventory)(CORO_PARAM, uint32 dwCode, uint32, uint32, uint32) {
|
||||
Inventory->RemoveItem(dwCode);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeInventoryStatus)(uint32 dwCode, uint32 dwStatus, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(ChangeInventoryStatus)(CORO_PARAM, uint32 dwCode, uint32 dwStatus, uint32, uint32) {
|
||||
Inventory->ChangeItemStatus(dwCode,dwStatus);
|
||||
}
|
||||
|
||||
@ -1452,7 +1481,7 @@ DECLARE_CUSTOM_FUNCTION(ChangeInventoryStatus)(uint32 dwCode, uint32 dwStatus, u
|
||||
* Mastri Personaggi
|
||||
*/
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetCode)(uint32 nChar, uint32 nCode, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetCode)(CORO_PARAM, uint32 nChar, uint32 nCode, uint32, uint32) {
|
||||
assert(nChar < 10);
|
||||
MCharacter[nChar].code=nCode;
|
||||
if (nCode== 0)
|
||||
@ -1474,19 +1503,19 @@ DECLARE_CUSTOM_FUNCTION(MCharSetCode)(uint32 nChar, uint32 nCode, uint32, uint32
|
||||
IsMChar[nChar] = true;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharResetCode)(uint32 nChar, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharResetCode)(CORO_PARAM, uint32 nChar, uint32, uint32, uint32) {
|
||||
MCharacter[nChar].item=Loc->GetItemFromCode(MCharacter[nChar].code);
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetPosition)(uint32 nChar, uint32 nX, uint32 nY, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetPosition)(CORO_PARAM, uint32 nChar, uint32 nX, uint32 nY, uint32) {
|
||||
assert(nChar < 10);
|
||||
MCharacter[nChar].x=nX;
|
||||
MCharacter[nChar].y=nY;
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetColor)(uint32 nChar, uint32 r, uint32 g, uint32 b) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetColor)(CORO_PARAM, uint32 nChar, uint32 r, uint32 g, uint32 b) {
|
||||
assert(nChar < 10);
|
||||
MCharacter[nChar].r=r;
|
||||
MCharacter[nChar].g=g;
|
||||
@ -1494,7 +1523,7 @@ DECLARE_CUSTOM_FUNCTION(MCharSetColor)(uint32 nChar, uint32 r, uint32 g, uint32
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetNumTalksInGroup)(uint32 nChar, uint32 nGroup, uint32 nTalks, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetNumTalksInGroup)(CORO_PARAM, uint32 nChar, uint32 nGroup, uint32 nTalks, uint32) {
|
||||
assert(nChar < 10);
|
||||
assert(nGroup < 10);
|
||||
|
||||
@ -1502,7 +1531,7 @@ DECLARE_CUSTOM_FUNCTION(MCharSetNumTalksInGroup)(uint32 nChar, uint32 nGroup, ui
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetCurrentGroup)(uint32 nChar, uint32 nGroup, uint32, uint32)
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetCurrentGroup)(CORO_PARAM, uint32 nChar, uint32 nGroup, uint32, uint32)
|
||||
{
|
||||
assert(nChar < 10);
|
||||
assert(nGroup < 10);
|
||||
@ -1510,21 +1539,21 @@ DECLARE_CUSTOM_FUNCTION(MCharSetCurrentGroup)(uint32 nChar, uint32 nGroup, uint3
|
||||
MCharacter[nChar].curgroup = nGroup;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetNumTexts)(uint32 nChar, uint32 nTexts, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetNumTexts)(CORO_PARAM, uint32 nChar, uint32 nTexts, uint32, uint32) {
|
||||
assert(nChar < 10);
|
||||
|
||||
MCharacter[nChar].numtexts=nTexts-1;
|
||||
MCharacter[nChar].bInTexts = false;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetAlwaysBack)(uint32 nChar, uint32 bAlwaysBack, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSetAlwaysBack)(CORO_PARAM, uint32 nChar, uint32 bAlwaysBack, uint32, uint32) {
|
||||
assert(nChar < 10);
|
||||
|
||||
MCharacter[nChar].bAlwaysBack=bAlwaysBack;
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(uint32 nChar, uint32 dwMessage, uint32 bIsBack, uint32 nFont) {
|
||||
DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMessage, uint32 bIsBack, uint32 nFont) {
|
||||
RMMessage msg(dwMessage);
|
||||
int i;
|
||||
int parm;
|
||||
@ -1645,7 +1674,7 @@ DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(uint32 nChar, uint32 dwMessage, uint32
|
||||
|
||||
int curDialog;
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(uint32 nPers, uint32 nMsg, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg, uint32, uint32) {
|
||||
LPSTR string;
|
||||
RMTextDialog* text;
|
||||
int parm;
|
||||
@ -1822,7 +1851,7 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(uint32 nPers, uint32 nMsg, uint32, ui
|
||||
|
||||
// @@@@ QUESTA NON SI PUO' SKIPPARE!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(StartDialog)(uint32 nDialog, uint32 nStartGroup, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(StartDialog)(CORO_PARAM, uint32 nDialog, uint32 nStartGroup, uint32, uint32) {
|
||||
int nChoice;
|
||||
uint32 *sl;
|
||||
int i,num;
|
||||
@ -1897,12 +1926,12 @@ DECLARE_CUSTOM_FUNCTION(StartDialog)(uint32 nDialog, uint32 nStartGroup, uint32,
|
||||
* Sync tra idle e mpal
|
||||
*/
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(TakeOwnership)(uint32 num, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(TakeOwnership)(CORO_PARAM, uint32 num, uint32, uint32, uint32) {
|
||||
// EnterCriticalSection(&cs[num]);
|
||||
WaitForSingleObject(mut[num],INFINITE);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(ReleaseOwnership)(uint32 num, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(ReleaseOwnership)(CORO_PARAM, uint32 num, uint32, uint32, uint32) {
|
||||
// LeaveCriticalSection(&cs[num]);
|
||||
// g_system->unlockMutex(mut[num]);
|
||||
warning("TODO: ReleaseOwnership");
|
||||
@ -1975,46 +2004,46 @@ void ThreadFadeOutMusic(void *nMusic) {
|
||||
_endthread();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(FadeInSonoriz)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(FadeInSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_beginthread(ThreadFadeInMusic, 10240, (void*)curSonoriz);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(FadeOutSonoriz)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(FadeOutSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
bFadeOutStop = false;
|
||||
_beginthread(ThreadFadeOutMusic, 10240, (void *)curSonoriz);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(FadeOutStacchetto)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(FadeOutStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
bFadeOutStop = false;
|
||||
_beginthread(ThreadFadeOutMusic, 10240, (void*)2);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(FadeInStacchetto)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(FadeInStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_beginthread(ThreadFadeInMusic, 10240, (void*)2);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(StopSonoriz)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(StopSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_vm->StopMusic(curSonoriz);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(StopStacchetto)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(StopStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_vm->StopMusic(2);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MuteSonoriz)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MuteSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_vm->SetMusicVolume(curSonoriz, 0);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(DemuteSonoriz)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(DemuteSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
bFadeOutStop = true;
|
||||
_vm->SetMusicVolume(curSonoriz, 64);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MuteStacchetto)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MuteStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_vm->SetMusicVolume(2, 0);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(DemuteStacchetto)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(DemuteStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
_vm->SetMusicVolume(2, 64);
|
||||
}
|
||||
|
||||
@ -2139,7 +2168,7 @@ void CustPlayMusic(uint32 nChannel, const char *mFN, uint32 nFX, bool bLoop, int
|
||||
debug("End CustPlayMusic\n");
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(PlaySonoriz)(uint32 nMusic, uint32 nFX, uint32 bNoLoop, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(PlaySonoriz)(CORO_PARAM, uint32 nMusic, uint32 nFX, uint32 bNoLoop, uint32) {
|
||||
if (nFX == 0 || nFX == 1 || nFX==2) {
|
||||
debug("PlaySonoriz stop fadeout\n");
|
||||
bFadeOutStop = true;
|
||||
@ -2149,11 +2178,11 @@ DECLARE_CUSTOM_FUNCTION(PlaySonoriz)(uint32 nMusic, uint32 nFX, uint32 bNoLoop,
|
||||
CustPlayMusic(curSonoriz, musicFiles[nMusic].name, nFX, bNoLoop ? false : true, musicFiles[nMusic].sync);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(PlayStacchetto)(uint32 nMusic, uint32 nFX, uint32 bLoop, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(PlayStacchetto)(CORO_PARAM, uint32 nMusic, uint32 nFX, uint32 bLoop, uint32) {
|
||||
CustPlayMusic(2,staccFileNames[nMusic],nFX,bLoop);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(PlayItemSfx)(uint32 nItem, uint32 nSFX, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(PlayItemSfx)(CORO_PARAM, uint32 nItem, uint32 nSFX, uint32, uint32) {
|
||||
if (nItem== 0) {
|
||||
Tony->PlaySfx(nSFX);
|
||||
} else {
|
||||
@ -2165,7 +2194,7 @@ DECLARE_CUSTOM_FUNCTION(PlayItemSfx)(uint32 nItem, uint32 nSFX, uint32, uint32)
|
||||
|
||||
|
||||
void RestoreMusic(void) {
|
||||
PlaySonoriz(lastMusic, 0, 0, 0);
|
||||
PlaySonoriz(nullContext, lastMusic, 0, 0, 0);
|
||||
if (lastTappeto != 0)
|
||||
CustPlayMusic(4, tappetiFile[lastTappeto], 0, true);
|
||||
}
|
||||
@ -2181,49 +2210,63 @@ void LoadMusic(Common::InSaveFile *f) {
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(StacchettoFadeStart)(uint32 nStacc, uint32 bLoop, uint32, uint32) {
|
||||
FadeOutSonoriz(0, 0, 0, 0);
|
||||
MuteStacchetto(0, 0, 0, 0);
|
||||
PlayStacchetto(nStacc, 0, bLoop, 0);
|
||||
FadeInStacchetto(0, 0, 0, 0);
|
||||
DECLARE_CUSTOM_FUNCTION(StacchettoFadeStart)(CORO_PARAM, uint32 nStacc, uint32 bLoop, uint32, uint32) {
|
||||
CORO_BEGIN_CONTEXT;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
CORO_INVOKE_4(FadeOutSonoriz, 0, 0, 0, 0);
|
||||
CORO_INVOKE_4(MuteStacchetto, 0, 0, 0, 0);
|
||||
CORO_INVOKE_4(PlayStacchetto, nStacc, 0, bLoop, 0);
|
||||
CORO_INVOKE_4(FadeInStacchetto, 0, 0, 0, 0);
|
||||
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(StacchettoFadeEnd)(uint32 nStacc, uint32 bLoop, uint32, uint32) {
|
||||
FadeOutStacchetto(0, 0, 0, 0);
|
||||
FadeInSonoriz(0, 0, 0, 0);
|
||||
DECLARE_CUSTOM_FUNCTION(StacchettoFadeEnd)(CORO_PARAM, uint32 nStacc, uint32 bLoop, uint32, uint32) {
|
||||
CORO_BEGIN_CONTEXT;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
CORO_INVOKE_4(FadeOutStacchetto, 0, 0, 0, 0);
|
||||
CORO_INVOKE_4(FadeInSonoriz, 0, 0, 0, 0);
|
||||
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MustSkipIdleStart)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MustSkipIdleStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
bSkipIdle = true;
|
||||
SetEvent(hSkipIdle);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(MustSkipIdleEnd)(uint32, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(MustSkipIdleEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
bSkipIdle = false;
|
||||
ResetEvent(hSkipIdle);
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(PatIrqFreeze)(uint32 bStatus, uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(PatIrqFreeze)(CORO_PARAM, uint32 bStatus, uint32, uint32, uint32) {
|
||||
bPatIrqFreeze = bStatus;
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(OpenInitLoadMenu)(uint32 , uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(OpenInitLoadMenu)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Freeze();
|
||||
_vm->OpenInitLoadMenu();
|
||||
Unfreeze();
|
||||
}
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(OpenInitOptions)(uint32 , uint32, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(OpenInitOptions)(CORO_PARAM, uint32, uint32, uint32, uint32) {
|
||||
Freeze();
|
||||
_vm->OpenInitOptions();
|
||||
Unfreeze();
|
||||
}
|
||||
|
||||
|
||||
DECLARE_CUSTOM_FUNCTION(DoCredits)(uint32 nMsg, uint32 dwTime, uint32, uint32) {
|
||||
DECLARE_CUSTOM_FUNCTION(DoCredits)(CORO_PARAM, uint32 nMsg, uint32 dwTime, uint32, uint32) {
|
||||
RMMessage msg(nMsg);
|
||||
RMTextDialog *text;
|
||||
HANDLE hDisable = CreateEvent(NULL, true, false, NULL);
|
||||
|
@ -67,10 +67,10 @@ typedef uint32 HWND;
|
||||
#define DECLARE_CUSTOM_FUNCTION(x) void x
|
||||
|
||||
#define BEGIN_CUSTOM_FUNCTION_MAP() \
|
||||
static void AssignError(HWND hWnd, int num) { \
|
||||
static void AssignError(int num) { \
|
||||
error("Custom function %u has been already assigned!", num); \
|
||||
} \
|
||||
void INIT_CUSTOM_FUNCTION(HWND hWnd, LPCUSTOMFUNCTION *lpMap) \
|
||||
void INIT_CUSTOM_FUNCTION(LPCUSTOMFUNCTION *lpMap) \
|
||||
{
|
||||
|
||||
|
||||
@ -78,10 +78,10 @@ typedef uint32 HWND;
|
||||
}
|
||||
|
||||
|
||||
#define ASSIGN(num,func) \
|
||||
if (lpMap[num]!=NULL) \
|
||||
AssignError(hWnd,num); \
|
||||
lpMap[num]=func;
|
||||
#define ASSIGN(num, func) \
|
||||
if (lpMap[num] != NULL) \
|
||||
AssignError(num); \
|
||||
lpMap[num] = func;
|
||||
|
||||
class RMTony;
|
||||
class RMPointer;
|
||||
@ -90,7 +90,7 @@ class RMLocation;
|
||||
class RMInventory;
|
||||
class RMInput;
|
||||
|
||||
void INIT_CUSTOM_FUNCTION(HWND hWnd, LPCUSTOMFUNCTION *lpMap);
|
||||
void INIT_CUSTOM_FUNCTION(LPCUSTOMFUNCTION *lpMap);
|
||||
void SetupGlobalVars(RMTony *tony, RMPointer *ptr, RMGameBoxes *box, RMLocation *loc, RMInventory *inv, RMInput *input);
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,7 @@
|
||||
MODULE := engines/tony
|
||||
|
||||
MODULE_OBJS := \
|
||||
coroutine.o \
|
||||
custom.o \
|
||||
detection.o \
|
||||
font.o \
|
||||
@ -10,6 +11,7 @@ MODULE_OBJS := \
|
||||
input.o \
|
||||
inventory.o \
|
||||
loc.o \
|
||||
sched.o \
|
||||
sound.o \
|
||||
tony.o \
|
||||
tonychar.o \
|
||||
|
@ -51,11 +51,12 @@
|
||||
#include "common/file.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/system.h"
|
||||
#include "tony/sched.h"
|
||||
#include "tony/tony.h"
|
||||
#include "lzo.h"
|
||||
#include "mpal.h"
|
||||
#include "mpaldll.h"
|
||||
#include "stubs.h"
|
||||
#include "tony/mpal/lzo.h"
|
||||
#include "tony/mpal/mpal.h"
|
||||
#include "tony/mpal/mpaldll.h"
|
||||
#include "tony/mpal/stubs.h"
|
||||
|
||||
namespace Tony {
|
||||
|
||||
@ -829,7 +830,10 @@ static LPITEM GetItemData(uint32 nOrdItem) {
|
||||
\****************************************************************************/
|
||||
|
||||
void PASCAL CustomThread(LPCFCALL p) {
|
||||
lplpFunctions[p->nCf](p->arg1, p->arg2, p->arg3, p->arg4);
|
||||
// FIXME: Convert to proper corotuine call
|
||||
warning("FIXME: CustomThread call");
|
||||
|
||||
lplpFunctions[p->nCf](nullContext, p->arg1, p->arg2, p->arg3, p->arg4);
|
||||
GlobalFree(p);
|
||||
ExitThread(1);
|
||||
// _endthread();
|
||||
@ -939,50 +943,69 @@ void PASCAL ScriptThread(LPMPALSCRIPT s) {
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
void PASCAL ActionThread(LPMPALITEM item) {
|
||||
int j, k;
|
||||
void ActionThread(CORO_PARAM, const void *param) {
|
||||
// COROUTINE
|
||||
CORO_BEGIN_CONTEXT;
|
||||
int j, k;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
for (j = 0;j<item->Action[item->dwRes].nCmds; j++) {
|
||||
k=item->Action[item->dwRes].CmdNum[j];
|
||||
const LPMPALITEM item = *(const LPMPALITEM *)param;
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
mpalError = 0;
|
||||
for (_ctx->j = 0; _ctx->j < item->Action[item->dwRes].nCmds; _ctx->j++) {
|
||||
_ctx->k = item->Action[item->dwRes].CmdNum[_ctx->j];
|
||||
|
||||
if (item->Command[_ctx->k].type == 1) {
|
||||
// Custom function
|
||||
CORO_INVOKE_4(lplpFunctions[item->Command[_ctx->k].nCf],
|
||||
item->Command[_ctx->k].arg1,
|
||||
item->Command[_ctx->k].arg2,
|
||||
item->Command[_ctx->k].arg3,
|
||||
item->Command[_ctx->k].arg4
|
||||
|
||||
switch (item->Command[k].type) {
|
||||
case 1:
|
||||
// Funzione custom
|
||||
lplpFunctions[item->Command[k].nCf](
|
||||
item->Command[k].arg1,
|
||||
item->Command[k].arg2,
|
||||
item->Command[k].arg3,
|
||||
item->Command[k].arg4
|
||||
);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
} else if (item->Command[_ctx->k].type == 2) {
|
||||
// Variable assign
|
||||
LockVar();
|
||||
varSetValue(item->Command[k].lpszVarName, EvaluateExpression(item->Command[k].expr));
|
||||
varSetValue(item->Command[_ctx->k].lpszVarName, EvaluateExpression(item->Command[_ctx->k].expr));
|
||||
UnlockVar();
|
||||
break;
|
||||
|
||||
default:
|
||||
} else {
|
||||
mpalError = 1;
|
||||
ExitThread(0);
|
||||
// _endthread();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalFree(item);
|
||||
//bExecutingAction = false;
|
||||
|
||||
CORO_KILL_SELF();
|
||||
|
||||
ExitThread(1);
|
||||
// _endthread();
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
void PASCAL ShutUpActionThread(HANDLE hThread) {
|
||||
/**
|
||||
* This thread monitors a created action to detect when it ends.
|
||||
* @remarks Since actions can spawn sub-actions, this needs to be a
|
||||
* separate thread to determine when the outer action is done
|
||||
*/
|
||||
void ShutUpActionThread(CORO_PARAM, const void *param) {
|
||||
// COROUTINE
|
||||
CORO_BEGIN_CONTEXT;
|
||||
CORO_END_CONTEXT(_ctx);
|
||||
|
||||
HANDLE hThread = *(const HANDLE *)param;
|
||||
|
||||
CORO_BEGIN_CODE(_ctx);
|
||||
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
bExecutingAction = false;
|
||||
|
||||
ExitThread(1);
|
||||
// _endthread();
|
||||
CORO_KILL_SELF();
|
||||
|
||||
CORO_END_CODE;
|
||||
}
|
||||
|
||||
/****************************************************************************\
|
||||
@ -1241,7 +1264,8 @@ void PASCAL LocationPollThread(uint32 id) {
|
||||
*/
|
||||
|
||||
// Set idle skip on
|
||||
lplpFunctions[200](0, 0, 0, 0);
|
||||
// FIXME: Convert to co-routine
|
||||
lplpFunctions[200](nullContext, 0, 0, 0, 0);
|
||||
|
||||
for (i = 0; i < nRealItems; i++)
|
||||
if (MyThreads[i].nItem != 0) {
|
||||
@ -1252,7 +1276,8 @@ void PASCAL LocationPollThread(uint32 id) {
|
||||
}
|
||||
|
||||
// Set idle skip off
|
||||
lplpFunctions[201](0, 0, 0, 0);
|
||||
// FIXME: Convert to co-routine
|
||||
lplpFunctions[201](nullContext, 0, 0, 0, 0);
|
||||
|
||||
/* Abbiamo finito */
|
||||
GlobalFree(MyThreads);
|
||||
@ -1324,7 +1349,9 @@ void PASCAL GroupThread(uint32 nGroup) {
|
||||
switch (dialog->Command[k].type) {
|
||||
/* Funzione custom: la richiama */
|
||||
case 1:
|
||||
// FIXME: Convert to co-routine
|
||||
lplpFunctions[dialog->Command[k].nCf](
|
||||
nullContext,
|
||||
dialog->Command[k].arg1,
|
||||
dialog->Command[k].arg2,
|
||||
dialog->Command[k].arg3,
|
||||
@ -1488,8 +1515,7 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
|
||||
LPMPALITEM item = lpmiItems;
|
||||
int i;
|
||||
LPMPALITEM newitem;
|
||||
uint32 dwId;
|
||||
HANDLE h;
|
||||
PROCESS *h;
|
||||
|
||||
item+=ordItem;
|
||||
Common::String buf = Common::String::format("Status.%u", item->nObj);
|
||||
@ -1510,7 +1536,7 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
|
||||
|
||||
// Ora abbiamo trova l'azione giusta che deve essere eseguita.
|
||||
// Duplichiamo l'item corrente e copiamo la azione #i nella #0
|
||||
newitem=(LPMPALITEM)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(MPALITEM));
|
||||
newitem = (LPMPALITEM)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(MPALITEM));
|
||||
if (newitem == NULL)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
@ -1524,12 +1550,11 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
|
||||
// E finalmente possiamo richiamare il thread, che eseguira' l'azione
|
||||
// 0 dell'item, e poi liberera' la memoria con la GlobalFree()
|
||||
|
||||
/* !!! Nuova gestione dei thread
|
||||
*/
|
||||
if ((h = CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)ActionThread, (void *)newitem, 0, &dwId)) == NULL)
|
||||
// !!! New thread management
|
||||
if ((h = g_scheduler->createProcess(ActionThread, newitem)) == NULL)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
if ((h = CreateThread(NULL, 10240,(LPTHREAD_START_ROUTINE)ShutUpActionThread, (void *)h, 0, &dwId)) == NULL)
|
||||
if ((h = g_scheduler->createProcess(0, ShutUpActionThread, &h, sizeof(PROCESS *))) == NULL)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
/*
|
||||
@ -1543,7 +1568,7 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
|
||||
nExecutingAction = item->nObj;
|
||||
bExecutingAction = true;
|
||||
|
||||
return h;
|
||||
return (HANDLE)h;
|
||||
}
|
||||
|
||||
return INVALID_HANDLE_VALUE;
|
||||
@ -1674,7 +1699,7 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName, LPLPCUST
|
||||
//printf("Dialog: %lu\n", sizeof(MPALDIALOG));
|
||||
|
||||
/* Si salva l'array delle funzioni custom */
|
||||
lplpFunctions=lplpcfArray;
|
||||
lplpFunctions = lplpcfArray;
|
||||
|
||||
/* Apre il file MPC in lettura */
|
||||
if (!hMpc.open(lpszMpcFileName))
|
||||
|
@ -119,6 +119,7 @@
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/rect.h"
|
||||
#include "tony/coroutine.h"
|
||||
|
||||
namespace Tony {
|
||||
|
||||
@ -220,7 +221,7 @@ typedef ITEM *LPITEM;
|
||||
* to perform various controls as a result of an action
|
||||
\****************************************************************************/
|
||||
|
||||
typedef void (*LPCUSTOMFUNCTION)(uint32, uint32, uint32, uint32);
|
||||
typedef void (*LPCUSTOMFUNCTION)(CORO_PARAM, uint32, uint32, uint32, uint32);
|
||||
typedef LPCUSTOMFUNCTION *LPLPCUSTOMFUNCTION;
|
||||
|
||||
|
||||
|
498
engines/tony/sched.cpp
Normal file
498
engines/tony/sched.cpp
Normal file
@ -0,0 +1,498 @@
|
||||
/* 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.
|
||||
*
|
||||
* Process scheduler.
|
||||
*/
|
||||
|
||||
#include "common/textconsole.h"
|
||||
#include "common/util.h"
|
||||
#include "tony/sched.h"
|
||||
|
||||
namespace Tony {
|
||||
|
||||
Scheduler *g_scheduler = 0;
|
||||
|
||||
//--------------------- FUNCTIONS ------------------------
|
||||
|
||||
Scheduler::Scheduler() {
|
||||
processList = NULL;
|
||||
pFreeProcesses = NULL;
|
||||
pCurrent = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
// diagnostic process counters
|
||||
numProcs = 0;
|
||||
maxProcs = 0;
|
||||
#endif
|
||||
|
||||
pRCfunction = 0;
|
||||
|
||||
active = new PROCESS;
|
||||
active->pPrevious = NULL;
|
||||
active->pNext = NULL;
|
||||
|
||||
g_scheduler = this; // FIXME HACK
|
||||
}
|
||||
|
||||
Scheduler::~Scheduler() {
|
||||
// Kill all running processes (i.e. free memory allocated for their state).
|
||||
PROCESS *pProc = active->pNext;
|
||||
while (pProc != NULL) {
|
||||
delete pProc->state;
|
||||
pProc->state = 0;
|
||||
pProc = pProc->pNext;
|
||||
}
|
||||
|
||||
free(processList);
|
||||
processList = NULL;
|
||||
|
||||
delete active;
|
||||
active = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills all processes and places them on the free list.
|
||||
*/
|
||||
void Scheduler::reset() {
|
||||
|
||||
#ifdef DEBUG
|
||||
// clear number of process in use
|
||||
numProcs = 0;
|
||||
#endif
|
||||
|
||||
if (processList == NULL) {
|
||||
// first time - allocate memory for process list
|
||||
processList = (PROCESS *)calloc(MAX_PROCESSES, sizeof(PROCESS));
|
||||
|
||||
// make sure memory allocated
|
||||
if (processList == NULL) {
|
||||
error("Cannot allocate memory for process data");
|
||||
}
|
||||
|
||||
// fill with garbage
|
||||
memset(processList, 'S', MAX_PROCESSES * sizeof(PROCESS));
|
||||
}
|
||||
|
||||
// Kill all running processes (i.e. free memory allocated for their state).
|
||||
PROCESS *pProc = active->pNext;
|
||||
while (pProc != NULL) {
|
||||
delete pProc->state;
|
||||
pProc->state = 0;
|
||||
pProc = pProc->pNext;
|
||||
}
|
||||
|
||||
// no active processes
|
||||
pCurrent = active->pNext = NULL;
|
||||
|
||||
// place first process on free list
|
||||
pFreeProcesses = processList;
|
||||
|
||||
// link all other processes after first
|
||||
for (int i = 1; i <= NUM_PROCESS; i++) {
|
||||
processList[i - 1].pNext = (i == NUM_PROCESS) ? NULL : processList + i;
|
||||
processList[i - 1].pPrevious = (i == 1) ? active : processList + (i - 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* Shows the maximum number of process used at once.
|
||||
*/
|
||||
void Scheduler::printStats() {
|
||||
debug("%i process of %i used", maxProcs, NUM_PROCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* Checks both the active and free process list to insure all the links are valid,
|
||||
* and that no processes have been lost
|
||||
*/
|
||||
void Scheduler::CheckStack() {
|
||||
Common::List<PROCESS *> pList;
|
||||
|
||||
// Check both the active and free process lists
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
PROCESS *p = (i == 0) ? active : pFreeProcesses;
|
||||
|
||||
if (p != NULL) {
|
||||
// Make sure the linkages are correct
|
||||
while (p->pNext != NULL) {
|
||||
assert(p->pNext->pPrevious == p);
|
||||
pList.push_back(p);
|
||||
p = p->pNext;
|
||||
}
|
||||
pList.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure all processes are accounted for
|
||||
for (int idx = 0; idx < NUM_PROCESS; idx++) {
|
||||
bool found = false;
|
||||
for (Common::List<PROCESS *>::iterator i = pList.begin(); i != pList.end(); ++i) {
|
||||
PROCESS *pTemp = *i;
|
||||
if (*i == &processList[idx]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(found);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Give all active processes a chance to run
|
||||
*/
|
||||
void Scheduler::schedule() {
|
||||
// start dispatching active process list
|
||||
PROCESS *pNext;
|
||||
PROCESS *pProc = active->pNext;
|
||||
while (pProc != NULL) {
|
||||
pNext = pProc->pNext;
|
||||
|
||||
if (--pProc->sleepTime <= 0) {
|
||||
// process is ready for dispatch, activate it
|
||||
pCurrent = pProc;
|
||||
pProc->coroAddr(pProc->state, pProc->param);
|
||||
|
||||
if (!pProc->state || pProc->state->_sleep <= 0) {
|
||||
// Coroutine finished
|
||||
pCurrent = pCurrent->pPrevious;
|
||||
killProcess(pProc);
|
||||
} else {
|
||||
pProc->sleepTime = pProc->state->_sleep;
|
||||
}
|
||||
|
||||
// pCurrent may have been changed
|
||||
pNext = pCurrent->pNext;
|
||||
pCurrent = NULL;
|
||||
}
|
||||
|
||||
pProc = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reschedules all the processes to run again this query
|
||||
*/
|
||||
void Scheduler::rescheduleAll() {
|
||||
assert(pCurrent);
|
||||
|
||||
// Unlink current process
|
||||
pCurrent->pPrevious->pNext = pCurrent->pNext;
|
||||
if (pCurrent->pNext)
|
||||
pCurrent->pNext->pPrevious = pCurrent->pPrevious;
|
||||
|
||||
// Add process to the start of the active list
|
||||
pCurrent->pNext = active->pNext;
|
||||
active->pNext->pPrevious = pCurrent;
|
||||
active->pNext = pCurrent;
|
||||
pCurrent->pPrevious = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the specified process has already run on this tick, make it run
|
||||
* again on the current tick.
|
||||
*/
|
||||
void Scheduler::reschedule(PPROCESS pReSchedProc) {
|
||||
// If not currently processing the schedule list, then no action is needed
|
||||
if (!pCurrent)
|
||||
return;
|
||||
|
||||
if (!pReSchedProc)
|
||||
pReSchedProc = pCurrent;
|
||||
|
||||
PPROCESS pEnd;
|
||||
|
||||
// Find the last process in the list.
|
||||
// But if the target process is down the list from here, do nothing
|
||||
for (pEnd = pCurrent; pEnd->pNext != NULL; pEnd = pEnd->pNext) {
|
||||
if (pEnd->pNext == pReSchedProc)
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pEnd->pNext == NULL);
|
||||
|
||||
// Could be in the middle of a KillProc()!
|
||||
// Dying process was last and this process was penultimate
|
||||
if (pReSchedProc->pNext == NULL)
|
||||
return;
|
||||
|
||||
// If we're moving the current process, move it back by one, so that the next
|
||||
// schedule() iteration moves to the now next one
|
||||
if (pCurrent == pReSchedProc)
|
||||
pCurrent = pCurrent->pPrevious;
|
||||
|
||||
// Unlink the process, and add it at the end
|
||||
pReSchedProc->pPrevious->pNext = pReSchedProc->pNext;
|
||||
pReSchedProc->pNext->pPrevious = pReSchedProc->pPrevious;
|
||||
pEnd->pNext = pReSchedProc;
|
||||
pReSchedProc->pPrevious = pEnd;
|
||||
pReSchedProc->pNext = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the specified process to the end of the dispatch queue
|
||||
* allowing it to run again within the current game cycle.
|
||||
* @param pGiveProc Which process
|
||||
*/
|
||||
void Scheduler::giveWay(PPROCESS pReSchedProc) {
|
||||
// If not currently processing the schedule list, then no action is needed
|
||||
if (!pCurrent)
|
||||
return;
|
||||
|
||||
if (!pReSchedProc)
|
||||
pReSchedProc = pCurrent;
|
||||
|
||||
// If the process is already at the end of the queue, nothing has to be done
|
||||
if (!pReSchedProc->pNext)
|
||||
return;
|
||||
|
||||
PPROCESS pEnd;
|
||||
|
||||
// Find the last process in the list.
|
||||
for (pEnd = pCurrent; pEnd->pNext != NULL; pEnd = pEnd->pNext)
|
||||
;
|
||||
assert(pEnd->pNext == NULL);
|
||||
|
||||
|
||||
// If we're moving the current process, move it back by one, so that the next
|
||||
// schedule() iteration moves to the now next one
|
||||
if (pCurrent == pReSchedProc)
|
||||
pCurrent = pCurrent->pPrevious;
|
||||
|
||||
// Unlink the process, and add it at the end
|
||||
pReSchedProc->pPrevious->pNext = pReSchedProc->pNext;
|
||||
pReSchedProc->pNext->pPrevious = pReSchedProc->pPrevious;
|
||||
pEnd->pNext = pReSchedProc;
|
||||
pReSchedProc->pPrevious = pEnd;
|
||||
pReSchedProc->pNext = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new process.
|
||||
*
|
||||
* @param pid process identifier
|
||||
* @param CORO_ADDR coroutine start address
|
||||
* @param pParam process specific info
|
||||
* @param sizeParam size of process specific info
|
||||
*/
|
||||
PROCESS *Scheduler::createProcess(int pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam) {
|
||||
PROCESS *pProc;
|
||||
|
||||
// get a free process
|
||||
pProc = pFreeProcesses;
|
||||
|
||||
// trap no free process
|
||||
assert(pProc != NULL); // Out of processes
|
||||
|
||||
#ifdef DEBUG
|
||||
// one more process in use
|
||||
if (++numProcs > maxProcs)
|
||||
maxProcs = numProcs;
|
||||
#endif
|
||||
|
||||
// get link to next free process
|
||||
pFreeProcesses = pProc->pNext;
|
||||
if (pFreeProcesses)
|
||||
pFreeProcesses->pPrevious = NULL;
|
||||
|
||||
if (pCurrent != NULL) {
|
||||
// place new process before the next active process
|
||||
pProc->pNext = pCurrent->pNext;
|
||||
if (pProc->pNext)
|
||||
pProc->pNext->pPrevious = pProc;
|
||||
|
||||
// make this new process the next active process
|
||||
pCurrent->pNext = pProc;
|
||||
pProc->pPrevious = pCurrent;
|
||||
|
||||
} else { // no active processes, place process at head of list
|
||||
pProc->pNext = active->pNext;
|
||||
pProc->pPrevious = active;
|
||||
|
||||
if (pProc->pNext)
|
||||
pProc->pNext->pPrevious = pProc;
|
||||
active->pNext = pProc;
|
||||
|
||||
}
|
||||
|
||||
// set coroutine entry point
|
||||
pProc->coroAddr = coroAddr;
|
||||
|
||||
// clear coroutine state
|
||||
pProc->state = 0;
|
||||
|
||||
// wake process up as soon as possible
|
||||
pProc->sleepTime = 1;
|
||||
|
||||
// set new process id
|
||||
pProc->pid = pid;
|
||||
|
||||
// set new process specific info
|
||||
if (sizeParam) {
|
||||
assert(sizeParam > 0 && sizeParam <= PARAM_SIZE);
|
||||
|
||||
// set new process specific info
|
||||
memcpy(pProc->param, pParam, sizeParam);
|
||||
}
|
||||
|
||||
// return created process
|
||||
return pProc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills the specified process.
|
||||
*
|
||||
* @param pKillProc which process to kill
|
||||
*/
|
||||
void Scheduler::killProcess(PROCESS *pKillProc) {
|
||||
// make sure a valid process pointer
|
||||
assert(pKillProc >= processList && pKillProc <= processList + NUM_PROCESS - 1);
|
||||
|
||||
// can not kill the current process using killProcess !
|
||||
assert(pCurrent != pKillProc);
|
||||
|
||||
#ifdef DEBUG
|
||||
// one less process in use
|
||||
--numProcs;
|
||||
assert(numProcs >= 0);
|
||||
#endif
|
||||
|
||||
// Free process' resources
|
||||
if (pRCfunction != NULL)
|
||||
(pRCfunction)(pKillProc);
|
||||
|
||||
delete pKillProc->state;
|
||||
pKillProc->state = 0;
|
||||
|
||||
// Take the process out of the active chain list
|
||||
pKillProc->pPrevious->pNext = pKillProc->pNext;
|
||||
if (pKillProc->pNext)
|
||||
pKillProc->pNext->pPrevious = pKillProc->pPrevious;
|
||||
|
||||
// link first free process after pProc
|
||||
pKillProc->pNext = pFreeProcesses;
|
||||
if (pFreeProcesses)
|
||||
pKillProc->pNext->pPrevious = pKillProc;
|
||||
pKillProc->pPrevious = NULL;
|
||||
|
||||
// make pKillProc the first free process
|
||||
pFreeProcesses = pKillProc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a pointer to the currently running process.
|
||||
*/
|
||||
PROCESS *Scheduler::getCurrentProcess() {
|
||||
return pCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the process identifier of the specified process.
|
||||
*
|
||||
* @param pProc which process
|
||||
*/
|
||||
int Scheduler::getCurrentPID() const {
|
||||
PROCESS *pProc = pCurrent;
|
||||
|
||||
// make sure a valid process pointer
|
||||
assert(pProc >= processList && pProc <= processList + NUM_PROCESS - 1);
|
||||
|
||||
// return processes PID
|
||||
return pProc->pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills any process matching the specified PID. The current
|
||||
* process cannot be killed.
|
||||
*
|
||||
* @param pidKill process identifier of process to kill
|
||||
* @param pidMask mask to apply to process identifiers before comparison
|
||||
* @return The number of processes killed is returned.
|
||||
*/
|
||||
int Scheduler::killMatchingProcess(int pidKill, int pidMask) {
|
||||
int numKilled = 0;
|
||||
PROCESS *pProc, *pPrev; // process list pointers
|
||||
|
||||
for (pProc = active->pNext, pPrev = active; pProc != NULL; pPrev = pProc, pProc = pProc->pNext) {
|
||||
if ((pProc->pid & pidMask) == pidKill) {
|
||||
// found a matching process
|
||||
|
||||
// dont kill the current process
|
||||
if (pProc != pCurrent) {
|
||||
// kill this process
|
||||
numKilled++;
|
||||
|
||||
// Free the process' resources
|
||||
if (pRCfunction != NULL)
|
||||
(pRCfunction)(pProc);
|
||||
|
||||
delete pProc->state;
|
||||
pProc->state = 0;
|
||||
|
||||
// make prev point to next to unlink pProc
|
||||
pPrev->pNext = pProc->pNext;
|
||||
if (pProc->pNext)
|
||||
pPrev->pNext->pPrevious = pPrev;
|
||||
|
||||
// link first free process after pProc
|
||||
pProc->pNext = pFreeProcesses;
|
||||
pProc->pPrevious = NULL;
|
||||
pFreeProcesses->pPrevious = pProc;
|
||||
|
||||
// make pProc the first free process
|
||||
pFreeProcesses = pProc;
|
||||
|
||||
// set to a process on the active list
|
||||
pProc = pPrev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// adjust process in use
|
||||
numProcs -= numKilled;
|
||||
assert(numProcs >= 0);
|
||||
#endif
|
||||
|
||||
// return number of processes killed
|
||||
return numKilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pointer to a function to be called by killProcess().
|
||||
*
|
||||
* May be called by a resource allocator, the function supplied is
|
||||
* called by killProcess() to allow the resource allocator to free
|
||||
* resources allocated to the dying process.
|
||||
*
|
||||
* @param pFunc Function to be called by killProcess()
|
||||
*/
|
||||
void Scheduler::setResourceCallback(VFPTRPP pFunc) {
|
||||
pRCfunction = pFunc;
|
||||
}
|
||||
|
||||
} // End of namespace Tony
|
128
engines/tony/sched.h
Normal file
128
engines/tony/sched.h
Normal file
@ -0,0 +1,128 @@
|
||||
/* 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.
|
||||
*
|
||||
* Data structures used by the process scheduler
|
||||
*/
|
||||
|
||||
#ifndef TONY_SCHED_H
|
||||
#define TONY_SCHED_H
|
||||
|
||||
#include "tony/coroutine.h"
|
||||
|
||||
namespace Tony {
|
||||
|
||||
// the size of process specific info
|
||||
#define PARAM_SIZE 32
|
||||
|
||||
// the maximum number of processes
|
||||
#define NUM_PROCESS 100
|
||||
#define MAX_PROCESSES 100
|
||||
|
||||
typedef void (*CORO_ADDR)(CoroContext &, const void *);
|
||||
|
||||
/** process structure */
|
||||
struct PROCESS {
|
||||
PROCESS *pNext; ///< pointer to next process in active or free list
|
||||
PROCESS *pPrevious; ///< pointer to previous process in active or free list
|
||||
|
||||
CoroContext state; ///< the state of the coroutine
|
||||
CORO_ADDR coroAddr; ///< the entry point of the coroutine
|
||||
|
||||
int sleepTime; ///< number of scheduler cycles to sleep
|
||||
int pid; ///< process ID
|
||||
char param[PARAM_SIZE]; ///< process specific info
|
||||
};
|
||||
typedef PROCESS *PPROCESS;
|
||||
|
||||
struct INT_CONTEXT;
|
||||
|
||||
/**
|
||||
* Create and manage "processes" (really coroutines).
|
||||
*/
|
||||
class Scheduler {
|
||||
public:
|
||||
/** Pointer to a function of the form "void function(PPROCESS)" */
|
||||
typedef void (*VFPTRPP)(PROCESS *);
|
||||
|
||||
private:
|
||||
|
||||
/** list of all processes */
|
||||
PROCESS *processList;
|
||||
|
||||
/** active process list - also saves scheduler state */
|
||||
PROCESS *active;
|
||||
|
||||
/** pointer to free process list */
|
||||
PROCESS *pFreeProcesses;
|
||||
|
||||
/** the currently active process */
|
||||
PROCESS *pCurrent;
|
||||
|
||||
#ifdef DEBUG
|
||||
// diagnostic process counters
|
||||
int numProcs;
|
||||
int maxProcs;
|
||||
|
||||
void CheckStack();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Called from killProcess() to enable other resources
|
||||
* a process may be allocated to be released.
|
||||
*/
|
||||
VFPTRPP pRCfunction;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Scheduler();
|
||||
~Scheduler();
|
||||
|
||||
void reset();
|
||||
|
||||
#ifdef DEBUG
|
||||
void printStats();
|
||||
#endif
|
||||
|
||||
void schedule();
|
||||
void rescheduleAll();
|
||||
void reschedule(PPROCESS pReSchedProc = NULL);
|
||||
void giveWay(PPROCESS pReSchedProc = NULL);
|
||||
|
||||
PROCESS *createProcess(int pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam);
|
||||
PROCESS *createProcess(CORO_ADDR coroAddr, const void *pParam) {
|
||||
return createProcess(0, coroAddr, &pParam, sizeof(void *));
|
||||
}
|
||||
void killProcess(PROCESS *pKillProc);
|
||||
|
||||
PROCESS *getCurrentProcess();
|
||||
int getCurrentPID() const;
|
||||
int killMatchingProcess(int pidKill, int pidMask = -1);
|
||||
|
||||
|
||||
void setResourceCallback(VFPTRPP pFunc);
|
||||
|
||||
};
|
||||
|
||||
extern Scheduler *g_scheduler; // FIXME: Temporary global var, to be used until everything has been OOifyied
|
||||
|
||||
} // End of namespace Tony
|
||||
|
||||
#endif // TONY_SCHED_H
|
@ -26,6 +26,7 @@
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "tony/tony.h"
|
||||
#include "tony/custom.h"
|
||||
#include "tony/game.h"
|
||||
#include "tony/mpal/mpal.h"
|
||||
|
||||
@ -67,11 +68,15 @@ Common::ErrorCode TonyEngine::Init() {
|
||||
m_bDrawLocation = true;
|
||||
m_startTime = g_system->getMillis();
|
||||
|
||||
// Reset the scheduler
|
||||
_scheduler.reset();
|
||||
|
||||
// Initialise the graphics window
|
||||
_window.Init();
|
||||
|
||||
// Initialise the function list
|
||||
Common::fill(FuncList, FuncList + 300, (LPCUSTOMFUNCTION)NULL);
|
||||
InitCustomFunctionMap();
|
||||
|
||||
// Initializes MPAL system, passing the custom functions list
|
||||
Common::File f;
|
||||
@ -127,6 +132,10 @@ Common::ErrorCode TonyEngine::Init() {
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void TonyEngine::InitCustomFunctionMap() {
|
||||
INIT_CUSTOM_FUNCTION(FuncList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an error message
|
||||
*/
|
||||
@ -385,6 +394,9 @@ void TonyEngine::Play(void) {
|
||||
while (g_system->getEventManager()->pollEvent(evt))
|
||||
;
|
||||
|
||||
// Call any scheduled processes
|
||||
_scheduler.schedule();
|
||||
|
||||
// Call the engine to handle the next frame
|
||||
_theEngine.DoFrame(m_bDrawLocation);
|
||||
|
||||
@ -468,8 +480,7 @@ void TonyEngine::FreezeTime(void) {
|
||||
m_nTimeFreezed = GetTime() - m_startTime;
|
||||
}
|
||||
|
||||
void TonyEngine::UnfreezeTime(void)
|
||||
{
|
||||
void TonyEngine::UnfreezeTime(void) {
|
||||
m_bTimeFreezed = false;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "tony/mpal/memory.h"
|
||||
#include "tony/gfxengine.h"
|
||||
#include "tony/loc.h"
|
||||
#include "tony/sched.h"
|
||||
#include "tony/utils.h"
|
||||
#include "tony/window.h"
|
||||
|
||||
@ -80,6 +81,7 @@ private:
|
||||
void CloseMusic();
|
||||
bool OpenVoiceDatabase();
|
||||
void CloseVoiceDatabase();
|
||||
void InitCustomFunctionMap();
|
||||
protected:
|
||||
// Engine APIs
|
||||
virtual Common::Error run();
|
||||
@ -93,6 +95,7 @@ public:
|
||||
Common::File _vdbFP;
|
||||
Common::Array<VoiceHeader> _voices;
|
||||
FPSOUND _theSound;
|
||||
Scheduler _scheduler;
|
||||
|
||||
enum DATADIR {
|
||||
DD_BASE = 1,
|
||||
@ -140,9 +143,6 @@ public:
|
||||
// Loop che gestisce i messaggi quando siamo in pausa
|
||||
void PauseLoop(void);
|
||||
|
||||
// Carica un modulo e le sue funzioni custom
|
||||
void InitCustomDll(LPCUSTOMFUNCTION *FuncList);
|
||||
|
||||
void Play();
|
||||
void Close();
|
||||
void Abort();
|
||||
|
@ -224,7 +224,7 @@ void RMTony::ExecuteAction(int nAction, int nActionItem, int nParm) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Esegue l'azione
|
||||
// Perform the action
|
||||
hThread = mpalQueryDoAction(nAction, nActionItem, 0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user