scummvm/engines/tinsel/effect.cpp
Jakob Wagner 67c3bce30e TINSEL: Replace TinselV2 checks with comparisons
Until now, the TinselV* defines were used for discerning between
engine versions. The define TinselV2 was true for both v2 and v3.
Sticking to the old scheme would lead to confusion when more
special paths for v3 are implemented.
2022-04-21 20:34:17 +03:00

140 lines
3.8 KiB
C++

/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
// Handles effect polygons.
//
// EffectPolyProcess() monitors triggering of effect code (i.e. a moving
// actor entering an effect polygon).
// EffectProcess() runs the appropriate effect code.
//
// NOTE: Currently will only run one effect process at a time, i.e.
// effect polygons will not currently nest. It won't be very difficult
// to fix this if required.
#include "tinsel/actors.h"
#include "tinsel/dw.h"
#include "tinsel/events.h"
#include "tinsel/pid.h"
#include "tinsel/pcode.h" // LEAD_ACTOR
#include "tinsel/polygons.h"
#include "tinsel/movers.h"
#include "tinsel/sched.h"
#include "tinsel/tinsel.h"
namespace Tinsel {
struct EP_INIT {
HPOLYGON hEpoly;
MOVER *pMover;
int index;
};
/**
* Runs an effect polygon's Glitter code with ENTER event, waits for the
* actor to leave that polygon. Then runs the polygon's Glitter code
* with LEAVE event.
*/
static void EffectProcess(CORO_PARAM, const void *param) {
// COROUTINE
CORO_BEGIN_CONTEXT;
CORO_END_CONTEXT(_ctx);
const EP_INIT *to = (const EP_INIT *)param; // get the stuff copied to process when it was created
CORO_BEGIN_CODE(_ctx);
int x, y; // Lead actor position
// Run effect poly enter script
if (TinselVersion >= 2)
CORO_INVOKE_ARGS(PolygonEvent, (CORO_SUBCTX, to->hEpoly, WALKIN,
GetMoverId(to->pMover), false, 0));
else
effRunPolyTinselCode(to->hEpoly, WALKIN, to->pMover->actorID);
do {
CORO_SLEEP(1);
GetMoverPosition(to->pMover, &x, &y);
} while (InPolygon(x, y, EFFECT) == to->hEpoly);
// Run effect poly leave script
if (TinselVersion >= 2)
CORO_INVOKE_ARGS(PolygonEvent, (CORO_SUBCTX, to->hEpoly, WALKOUT,
GetMoverId(to->pMover), false, 0));
else
effRunPolyTinselCode(to->hEpoly, WALKOUT, to->pMover->actorID);
SetMoverInEffect(to->index, false);
CORO_END_CODE;
}
/**
* If the actor was not already in an effect polygon, checks to see if
* it has just entered one. If it has, a process is started up to run
* the polygon's Glitter code.
*/
static void FettleEffectPolys(int x, int y, int index, MOVER *pActor) {
HPOLYGON hPoly;
EP_INIT epi;
// If just entered an effect polygon, the effect should be triggered.
if (!IsMAinEffectPoly(index)) {
hPoly = InPolygon(x, y, EFFECT);
if (hPoly != NOPOLY) {
//Just entered effect polygon
SetMoverInEffect(index, true);
epi.hEpoly = hPoly;
epi.pMover = pActor;
epi.index = index;
CoroScheduler.createProcess(PID_TCODE, EffectProcess, &epi, sizeof(epi));
}
}
}
/**
* Just calls FettleEffectPolys() every clock tick.
*/
void EffectPolyProcess(CORO_PARAM, const void *param) {
// COROUTINE
CORO_BEGIN_CONTEXT;
CORO_END_CONTEXT(_ctx);
CORO_BEGIN_CODE(_ctx);
while (1) {
for (int i = 0; i < MAX_MOVERS; i++) {
MOVER *pActor = GetLiveMover(i);
if (pActor != NULL) {
int x, y;
GetMoverPosition(pActor, &x, &y);
FettleEffectPolys(x, y, i, pActor);
}
}
CORO_SLEEP(1); // allow re-scheduling
}
CORO_END_CODE;
}
} // End of namespace Tinsel