mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 06:41:51 +00:00
some work in progress on verb stuff:
- many structers and fields renamed to proper names - added missing functions svn-id: r16562
This commit is contained in:
parent
139f57a29d
commit
2f20dd57c2
118
saga/actor.cpp
118
saga/actor.cpp
@ -135,7 +135,8 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
|
||||
size_t stringsLength;
|
||||
ActorData *actor;
|
||||
debug(9, "Actor::Actor()");
|
||||
|
||||
|
||||
_actors = NULL;
|
||||
if (_vm->getGameType() == GType_IHNM) {
|
||||
warning("Actors aren't implemented for IHNM yet");
|
||||
return;
|
||||
@ -180,32 +181,37 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
|
||||
_vm->loadStrings(_actorsStrings, stringsPointer, stringsLength);
|
||||
RSC_FreeResource(stringsPointer);
|
||||
|
||||
for (i = 0; i < ACTORCOUNT; i++) {
|
||||
actor = &_actors[i];
|
||||
actor->actorId = actorIndexToId(i);
|
||||
actor->index = i;
|
||||
debug(9, "init actorId=%d index=%d", actor->actorId, actor->index);
|
||||
actor->nameIndex = ActorTable[i].nameIndex;
|
||||
actor->spriteListResourceId = ActorTable[i].spriteListResourceId;
|
||||
actor->frameListResourceId = ActorTable[i].frameListResourceId;
|
||||
actor->speechColor = ActorTable[i].speechColor;
|
||||
actor->sceneNumber = ActorTable[i].sceneIndex;
|
||||
actor->flags = ActorTable[i].flags;
|
||||
actor->currentAction = ActorTable[i].currentAction;
|
||||
actor->facingDirection = ActorTable[i].facingDirection;
|
||||
actor->actionDirection = ActorTable[i].actionDirection;
|
||||
actor->frameNumber = 0;
|
||||
actor->targetObject = ID_NOTHING;
|
||||
actor->actorFlags = 0;
|
||||
if (_vm->getGameType() == GType_ITE) {
|
||||
_actorsCount = ITE_ACTORCOUNT;
|
||||
_actors = (ActorData **)malloc(_actorsCount * sizeof(ActorData *));
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i] = new ActorData();
|
||||
actor->actorId = actorIndexToId(i);
|
||||
actor->index = i;
|
||||
debug(9, "init actorId=%d index=%d", actor->actorId, actor->index);
|
||||
actor->nameIndex = ITE_ActorTable[i].nameIndex;
|
||||
actor->scriptEntrypointNumber = ITE_ActorTable[i].scriptEntrypointNumber;
|
||||
actor->spriteListResourceId = ITE_ActorTable[i].spriteListResourceId;
|
||||
actor->frameListResourceId = ITE_ActorTable[i].frameListResourceId;
|
||||
actor->speechColor = ITE_ActorTable[i].speechColor;
|
||||
actor->sceneNumber = ITE_ActorTable[i].sceneIndex;
|
||||
actor->flags = ITE_ActorTable[i].flags;
|
||||
actor->currentAction = ITE_ActorTable[i].currentAction;
|
||||
actor->facingDirection = ITE_ActorTable[i].facingDirection;
|
||||
actor->actionDirection = ITE_ActorTable[i].actionDirection;
|
||||
actor->frameNumber = 0;
|
||||
actor->targetObject = ID_NOTHING;
|
||||
actor->actorFlags = 0;
|
||||
|
||||
actor->location.x = ActorTable[i].x;
|
||||
actor->location.y = ActorTable[i].y;
|
||||
actor->location.z = ActorTable[i].z;
|
||||
actor->location.x = ITE_ActorTable[i].x;
|
||||
actor->location.y = ITE_ActorTable[i].y;
|
||||
actor->location.z = ITE_ActorTable[i].z;
|
||||
|
||||
actor->disabled = !loadActorResources(actor);
|
||||
if (actor->disabled) {
|
||||
warning("Disabling actorId=%d index=%d", actor->actorId, actor->index);
|
||||
}
|
||||
actor->disabled = !loadActorResources(actor);
|
||||
if (actor->disabled) {
|
||||
warning("Disabling actorId=%d index=%d", actor->actorId, actor->index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,11 +231,11 @@ Actor::~Actor() {
|
||||
free(_pathCell);
|
||||
_actorsStrings.freeMem();
|
||||
//release resources
|
||||
for (i = 0; i < ACTORCOUNT; i++) {
|
||||
actor = &_actors[i];
|
||||
free(actor->frames);
|
||||
actor->spriteList.freeMem();
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i];
|
||||
delete actor;
|
||||
}
|
||||
free(_actors);
|
||||
}
|
||||
|
||||
bool Actor::loadActorResources(ActorData *actor) {
|
||||
@ -304,7 +310,7 @@ bool Actor::loadActorResources(ActorData *actor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFlags) {
|
||||
void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags) {
|
||||
int angle;
|
||||
int distance;
|
||||
ActorData *actor;
|
||||
@ -332,9 +338,9 @@ void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFl
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::actorFaceTowardsPoint(uint16 actorId, const ActorLocation &toLocation) {
|
||||
void Actor::actorFaceTowardsPoint(uint16 actorId, const Location &toLocation) {
|
||||
ActorData *actor;
|
||||
ActorLocation delta;
|
||||
Location delta;
|
||||
|
||||
actor = getActor(actorId);
|
||||
|
||||
@ -382,7 +388,7 @@ ActorData *Actor::getActor(uint16 actorId) {
|
||||
return _protagonist;
|
||||
}
|
||||
|
||||
actor = &_actors[actorIdToIndex(actorId)];
|
||||
actor = _actors[actorIdToIndex(actorId)];
|
||||
|
||||
if (actor->disabled)
|
||||
warning("Actor::getActor disabled actorId 0x%X", actorId);
|
||||
@ -390,7 +396,7 @@ ActorData *Actor::getActor(uint16 actorId) {
|
||||
return actor;
|
||||
}
|
||||
|
||||
bool Actor::validFollowerLocation(const ActorLocation &location) {
|
||||
bool Actor::validFollowerLocation(const Location &location) {
|
||||
Point point;
|
||||
location.toScreenPointXY(point);
|
||||
|
||||
@ -406,8 +412,8 @@ void Actor::updateActorsScene() {
|
||||
int i, j;
|
||||
int followerDirection;
|
||||
ActorData *actor;
|
||||
ActorLocation tempLocation;
|
||||
ActorLocation possibleLocation;
|
||||
Location tempLocation;
|
||||
Location possibleLocation;
|
||||
Point delta;
|
||||
|
||||
if (_vm->getGameType() == GType_IHNM) {
|
||||
@ -418,8 +424,8 @@ void Actor::updateActorsScene() {
|
||||
_activeSpeech.stringsCount = 0;
|
||||
_protagonist = NULL;
|
||||
|
||||
for (i = 0; i < ACTORCOUNT; i++) {
|
||||
actor = &_actors[i];
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i];
|
||||
if (actor->flags & (kProtagonist | kFollower)) {
|
||||
actor->sceneNumber = _vm->_scene->currentSceneNumber();
|
||||
if (actor->flags & kProtagonist) {
|
||||
@ -452,8 +458,8 @@ void Actor::updateActorsScene() {
|
||||
followerDirection = _protagonist->facingDirection + 3;
|
||||
calcActorScreenPosition(_protagonist);
|
||||
|
||||
for (i = 0; i < ACTORCOUNT; i++) {
|
||||
actor = &_actors[i];
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i];
|
||||
if (actor->flags & (kFollower)) {
|
||||
actor->facingDirection = actor->actionDirection = _protagonist->facingDirection;
|
||||
actor->currentAction = kActionWait;
|
||||
@ -630,11 +636,11 @@ void Actor::handleActions(int msec, bool setup) {
|
||||
ActorFrameRange *frameRange;
|
||||
int state;
|
||||
int speed;
|
||||
ActorLocation delta;
|
||||
ActorLocation addDelta;
|
||||
Location delta;
|
||||
Location addDelta;
|
||||
|
||||
for (i = 0; i < ACTORCOUNT; i++) {
|
||||
actor = &_actors[i];
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i];
|
||||
if (actor->disabled) continue;
|
||||
if (actor->sceneNumber != _vm->_scene->currentSceneNumber()) continue;
|
||||
|
||||
@ -876,7 +882,7 @@ int Actor::direct(int msec) {
|
||||
// FIXME: HACK. This should be turned into cycle event.
|
||||
_lastTickMsec += msec;
|
||||
|
||||
if (_lastTickMsec > ticksToMSec(5)) { // fixme
|
||||
if (_lastTickMsec > ticksToMSec(2)) { // fixme
|
||||
_lastTickMsec = 0;
|
||||
//process actions
|
||||
handleActions(msec, false);
|
||||
@ -922,8 +928,8 @@ void Actor::createDrawOrderList() {
|
||||
ActorData *actor;
|
||||
|
||||
_drawOrderList.clear();
|
||||
for (i = 0; i < ACTORCOUNT; i++) {
|
||||
actor = &_actors[i];
|
||||
for (i = 0; i < _actorsCount; i++) {
|
||||
actor = _actors[i];
|
||||
if (actor->disabled) continue;
|
||||
if (actor->sceneNumber != _vm->_scene->currentSceneNumber()) continue;
|
||||
|
||||
@ -1009,9 +1015,9 @@ int Actor::drawActors() {
|
||||
}
|
||||
|
||||
bool Actor::followProtagonist(ActorData *actor) {
|
||||
ActorLocation protagonistLocation;
|
||||
ActorLocation newLocation;
|
||||
ActorLocation delta;
|
||||
Location protagonistLocation;
|
||||
Location newLocation;
|
||||
Location delta;
|
||||
int protagonistBGMaskType;
|
||||
Point prefer1;
|
||||
Point prefer2;
|
||||
@ -1132,7 +1138,7 @@ bool Actor::actorEndWalk(uint16 actorId, bool recurse) {
|
||||
return walkMore;
|
||||
}
|
||||
|
||||
bool Actor::actorWalkTo(uint16 actorId, const ActorLocation &toLocation) {
|
||||
bool Actor::actorWalkTo(uint16 actorId, const Location &toLocation) {
|
||||
ActorData *actor;
|
||||
ActorData *anotherActor;
|
||||
int i;
|
||||
@ -1207,8 +1213,8 @@ bool Actor::actorWalkTo(uint16 actorId, const ActorLocation &toLocation) {
|
||||
|
||||
_barrierCount = 0;
|
||||
|
||||
for (i = 0; (i < ACTORCOUNT) && (_barrierCount < ACTOR_BARRIERS_MAX); i++) {
|
||||
anotherActor = &_actors[i];
|
||||
for (i = 0; (i < _actorsCount) && (_barrierCount < ACTOR_BARRIERS_MAX); i++) {
|
||||
anotherActor = _actors[i];
|
||||
if (anotherActor->disabled) continue;
|
||||
if (anotherActor->sceneNumber != _vm->_scene->currentSceneNumber()) continue;
|
||||
if (anotherActor == actor ) continue;
|
||||
@ -1298,8 +1304,8 @@ bool Actor::actorWalkTo(uint16 actorId, const ActorLocation &toLocation) {
|
||||
return false;
|
||||
} else {
|
||||
if (actor->flags & kProtagonist) {
|
||||
_actors[1].actorFlags &= ~kActorNoFollow;
|
||||
_actors[2].actorFlags &= ~kActorNoFollow;
|
||||
_actors[1]->actorFlags &= ~kActorNoFollow; // TODO: mark all actors with kFollower flag, not only 1 and 2
|
||||
_actors[2]->actorFlags &= ~kActorNoFollow;
|
||||
}
|
||||
actor->currentAction = (actor->walkStepsCount >= ACTOR_MAX_STEPS_COUNT) ? kActionWalkToLink : kActionWalkToPoint;
|
||||
actor->walkFrameSequence = kFrameWalk;
|
||||
@ -1903,7 +1909,7 @@ void Actor::drawPathTest() {
|
||||
|
||||
void Actor::cmdActorWalkTo(int argc, const char **argv) {
|
||||
uint16 actorId = (uint16) atoi(argv[1]);
|
||||
ActorLocation location;
|
||||
Location location;
|
||||
Point movePoint;
|
||||
|
||||
movePoint.x = atoi(argv[2]);
|
||||
|
36
saga/actor.h
36
saga/actor.h
@ -134,22 +134,22 @@ struct ActorFrameSequence {
|
||||
ActorFrameRange directions[ACTOR_DIRECTIONS_COUNT];
|
||||
};
|
||||
|
||||
struct ActorLocation {
|
||||
int x; // Actor's logical coordinates
|
||||
struct Location {
|
||||
int x; // logical coordinates
|
||||
int y; //
|
||||
int z; //
|
||||
ActorLocation() {
|
||||
Location() {
|
||||
x = y = z = 0;
|
||||
}
|
||||
int distance(const ActorLocation &location) const {
|
||||
int distance(const Location &location) const {
|
||||
return MAX(ABS(x - location.x), ABS(y - location.y));
|
||||
}
|
||||
void delta(const ActorLocation &location, ActorLocation &result) const {
|
||||
void delta(const Location &location, Location &result) const {
|
||||
result.x = x - location.x;
|
||||
result.y = y - location.y;
|
||||
result.z = z - location.z;
|
||||
}
|
||||
void add(const ActorLocation &location) {
|
||||
void add(const Location &location) {
|
||||
x += location.x;
|
||||
y += location.y;
|
||||
z += location.z;
|
||||
@ -176,10 +176,10 @@ struct ActorData {
|
||||
int nameIndex; // Actor's index in actor name string list
|
||||
byte speechColor; // Actor dialogue color
|
||||
uint16 flags; // Actor initial flags
|
||||
|
||||
int scriptEntrypointNumber; // Actor script entrypoint number
|
||||
|
||||
int sceneNumber; // scene of actor
|
||||
ActorLocation location; // Actor's logical coordinates
|
||||
Location location; // Actor's logical coordinates
|
||||
|
||||
Point screenPosition; // Actor's screen coordinates
|
||||
int screenDepth; //
|
||||
@ -211,8 +211,8 @@ struct ActorData {
|
||||
int walkStepIndex;
|
||||
Point *walkStepsPoints;
|
||||
|
||||
ActorLocation finalTarget;
|
||||
ActorLocation partialTarget;
|
||||
Location finalTarget;
|
||||
Location partialTarget;
|
||||
int walkFrameSequence;
|
||||
|
||||
void cycleWrap(int cycleLimit) {
|
||||
@ -235,7 +235,9 @@ struct ActorData {
|
||||
memset(&spriteList, 0, sizeof(spriteList));
|
||||
}
|
||||
~ActorData() {
|
||||
free(frames);
|
||||
free(walkStepsPoints);
|
||||
spriteList.freeMem();
|
||||
}
|
||||
};
|
||||
|
||||
@ -271,7 +273,7 @@ public:
|
||||
|
||||
void cmdActorWalkTo(int argc, const char **argv);
|
||||
|
||||
bool validActorId(uint16 id) { return (id == 1) || ((id >= 0x2000) && (id < (0x2000 | ACTORCOUNT))); }
|
||||
bool validActorId(uint16 id) { return (id == 1) || ((id >= 0x2000) && (id < (0x2000 | _actorsCount))); }
|
||||
int actorIdToIndex(uint16 id) { return (id == 1 ) ? 0 : (id & ~0x2000); }
|
||||
uint16 actorIndexToId(int index) { return (index == 0 ) ? 1 : (index | 0x2000); }
|
||||
|
||||
@ -281,13 +283,14 @@ public:
|
||||
|
||||
void drawPathTest();
|
||||
|
||||
uint16 testHit(const Point& mousePointer){ return ID_NOTHING;}; //TODO: do it
|
||||
const char * getActorName(uint16 actorId);
|
||||
bool actorEndWalk(uint16 actorId, bool recurse);
|
||||
bool actorWalkTo(uint16 actorId, const ActorLocation &toLocation);
|
||||
bool actorWalkTo(uint16 actorId, const Location &toLocation);
|
||||
ActorData *getActor(uint16 actorId);
|
||||
ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType);
|
||||
void realLocation(ActorLocation &location, uint16 objectId, uint16 walkFlags);
|
||||
void actorFaceTowardsPoint(uint16 actorId, const ActorLocation &toLocation);
|
||||
void realLocation(Location &location, uint16 objectId, uint16 walkFlags);
|
||||
void actorFaceTowardsPoint(uint16 actorId, const Location &toLocation);
|
||||
void actorFaceTowardsObject(uint16 actorId, uint16 objectId);
|
||||
|
||||
// speech
|
||||
@ -337,13 +340,14 @@ private:
|
||||
void removeNodes();
|
||||
void nodeToPath();
|
||||
void removePathPoints();
|
||||
bool validFollowerLocation(const ActorLocation &location);
|
||||
bool validFollowerLocation(const Location &location);
|
||||
|
||||
int _lastTickMsec;
|
||||
SagaEngine *_vm;
|
||||
RSCFILE_CONTEXT *_actorContext;
|
||||
ActorOrderList _drawOrderList;
|
||||
ActorData _actors[ACTORCOUNT];
|
||||
int _actorsCount;
|
||||
ActorData **_actors;
|
||||
SpeechData _activeSpeech;
|
||||
StringsTable _actorsStrings;
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
namespace Saga {
|
||||
|
||||
ActorTableData ActorTable[ACTORCOUNT] = {
|
||||
ActorTableData ITE_ActorTable[ITE_ACTORCOUNT] = {
|
||||
// Original used so called permanent actors for first three and that was designed by
|
||||
// EXTENDED object flag. They contained frames in more than one resource. We use
|
||||
// different technique here see "Apppending to sprite list" in loadActorResources()
|
||||
|
@ -49,16 +49,16 @@ struct ActorTableData {
|
||||
int16 z;
|
||||
int32 spriteListResourceId;
|
||||
int32 frameListResourceId;
|
||||
byte scriptResourceId;
|
||||
byte scriptEntrypointNumber;
|
||||
byte speechColor;
|
||||
byte currentAction;
|
||||
byte facingDirection;
|
||||
byte actionDirection;
|
||||
};
|
||||
|
||||
#define ACTORCOUNT 181
|
||||
#define ITE_ACTORCOUNT 181
|
||||
|
||||
extern ActorTableData ActorTable[ACTORCOUNT];
|
||||
extern ActorTableData ITE_ActorTable[ITE_ACTORCOUNT];
|
||||
|
||||
} // End of namespace Saga
|
||||
|
||||
|
@ -258,7 +258,7 @@ int Events::handleImmediate(EVENT *event) {
|
||||
|
||||
int Events::handleOneShot(EVENT *event) {
|
||||
SURFACE *back_buf;
|
||||
SCRIPT_THREAD *sthread;
|
||||
ScriptThread *sthread;
|
||||
Rect rect;
|
||||
|
||||
static SCENE_BGINFO bginfo;
|
||||
@ -397,7 +397,7 @@ int Events::handleOneShot(EVENT *event) {
|
||||
case EVENT_EXEC_NONBLOCKING:
|
||||
debug(0, "Starting start script #%d", event->param);
|
||||
|
||||
sthread = _vm->_script->SThreadCreate();
|
||||
sthread = _vm->_script->createThread();
|
||||
if (sthread == NULL) {
|
||||
_vm->_console->DebugPrintf("Thread creation failed.\n");
|
||||
break;
|
||||
@ -408,10 +408,10 @@ int Events::handleOneShot(EVENT *event) {
|
||||
sthread->threadVars[kVarWithObject] = TO_LE_16(event->param4);
|
||||
sthread->threadVars[kVarActor] = TO_LE_16(event->param5);
|
||||
|
||||
_vm->_script->SThreadExecute(sthread, event->param);
|
||||
_vm->_script->executeThread(sthread, event->param);
|
||||
|
||||
if (event->op == EVENT_EXEC_BLOCKING)
|
||||
_vm->_script->SThreadCompleteThread();
|
||||
_vm->_script->completeThread();
|
||||
|
||||
break;
|
||||
case EVENT_THREAD_WAKE:
|
||||
|
@ -41,7 +41,7 @@ SCENE_RESLIST IHNM_IntroMovie1RL[] = {
|
||||
{31, SAGA_ANIM_1, 0, 0}
|
||||
};
|
||||
|
||||
SCENE_DESC IHNM_IntroMovie1Desc = {
|
||||
SceneDescription IHNM_IntroMovie1Desc = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
IHNM_IntroMovie1RL,
|
||||
ARRAYSIZE(IHNM_IntroMovie1RL)
|
||||
@ -52,7 +52,7 @@ SCENE_RESLIST IHNM_IntroMovie2RL[] = {
|
||||
{33, SAGA_ANIM_1, 0, 0}
|
||||
};
|
||||
|
||||
SCENE_DESC IHNM_IntroMovie2Desc = {
|
||||
SceneDescription IHNM_IntroMovie2Desc = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
IHNM_IntroMovie2RL,
|
||||
ARRAYSIZE(IHNM_IntroMovie2RL)
|
||||
@ -63,7 +63,7 @@ SCENE_RESLIST IHNM_IntroMovie3RL[] = {
|
||||
{35, SAGA_ANIM_1, 0, 0}
|
||||
};
|
||||
|
||||
SCENE_DESC IHNM_IntroMovie3Desc = {
|
||||
SceneDescription IHNM_IntroMovie3Desc = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
IHNM_IntroMovie3RL,
|
||||
ARRAYSIZE(IHNM_IntroMovie3RL)
|
||||
@ -74,7 +74,7 @@ SCENE_RESLIST IHNM_IntroMovie4RL[] = {
|
||||
{1226, SAGA_ANIM_1, 0, 0}
|
||||
};
|
||||
|
||||
SCENE_DESC IHNM_IntroMovie4Desc = {
|
||||
SceneDescription IHNM_IntroMovie4Desc = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
IHNM_IntroMovie4RL,
|
||||
ARRAYSIZE(IHNM_IntroMovie4RL)
|
||||
|
@ -67,7 +67,7 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) {
|
||||
return;
|
||||
}
|
||||
|
||||
_iThread = _vm->_script->SThreadCreate();
|
||||
_iThread = _vm->_script->createThread();
|
||||
if (_iThread == NULL) {
|
||||
error("Interface::Interface(): Error creating script thread for game interface module");
|
||||
}
|
||||
@ -347,7 +347,7 @@ int Interface::draw() {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int Interface::update(const Point& imousePointer, int updateFlag) {
|
||||
int Interface::update(const Point& mousePoint, int updateFlag) {
|
||||
SURFACE *backBuffer;
|
||||
|
||||
|
||||
@ -358,31 +358,33 @@ int Interface::update(const Point& imousePointer, int updateFlag) {
|
||||
backBuffer = _vm->_gfx->getBackBuffer();
|
||||
|
||||
|
||||
if (_panelMode == kPanelMain) { // FIXME: HACK
|
||||
// Update playfield space ( only if cursor is inside )
|
||||
if (imousePointer.y < _vm->getSceneHeight()) {
|
||||
// Mouse is in playfield space
|
||||
if (updateFlag == UPDATE_MOUSEMOVE) {
|
||||
handlePlayfieldUpdate(backBuffer, imousePointer);
|
||||
if (_panelMode == kPanelMain) {
|
||||
if (updateFlag == UPDATE_MOUSEMOVE) {
|
||||
|
||||
if (mousePoint.y < _vm->getSceneHeight()) {
|
||||
//handlePlayfieldUpdate(backBuffer, imousePointer);
|
||||
_vm->_script->whichObject(mousePoint);
|
||||
} else {
|
||||
if (updateFlag == UPDATE_MOUSECLICK) {
|
||||
handlePlayfieldClick(backBuffer, imousePointer);
|
||||
if (_lastMousePoint.y < _vm->getSceneHeight()) {
|
||||
_vm->_script->setNonPlayfieldVerb();
|
||||
}
|
||||
handleCommandUpdate(backBuffer, mousePoint);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Update command space
|
||||
if (updateFlag == UPDATE_MOUSEMOVE) {
|
||||
handleCommandUpdate(backBuffer, imousePointer);
|
||||
} else {
|
||||
if (updateFlag == UPDATE_MOUSECLICK) {
|
||||
handleCommandClick(backBuffer, imousePointer);
|
||||
|
||||
if (updateFlag == UPDATE_MOUSECLICK) {
|
||||
if (mousePoint.y < _vm->getSceneHeight()) {
|
||||
handlePlayfieldClick(backBuffer, mousePoint);
|
||||
} else {
|
||||
handleCommandClick(backBuffer, mousePoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawStatusBar(backBuffer);
|
||||
|
||||
_lastMousePoint = mousePoint;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -415,21 +417,21 @@ int Interface::drawStatusBar(SURFACE *ds) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void Interface::handleCommandClick(SURFACE *ds, const Point& imousePointer) {
|
||||
void Interface::handleCommandClick(SURFACE *ds, const Point& mousePoint) {
|
||||
|
||||
PanelButton *panelButton;
|
||||
|
||||
panelButton = verbHitTest(imousePointer);
|
||||
panelButton = verbHitTest(mousePoint);
|
||||
if (panelButton) {
|
||||
_vm->_script->setVerb(panelButton->id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePointer) {
|
||||
void Interface::handleCommandUpdate(SURFACE *ds, const Point& mousePoint) {
|
||||
PanelButton *panelButton;
|
||||
|
||||
panelButton = verbHitTest(imousePointer);
|
||||
panelButton = verbHitTest(mousePoint);
|
||||
if (_mainPanel.currentButton != panelButton) {
|
||||
if (_mainPanel.currentButton) {
|
||||
drawVerb(_mainPanel.currentButton->id, 0);
|
||||
@ -458,7 +460,7 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
|
||||
uint16 object_flags = 0;
|
||||
|
||||
// int script_num;
|
||||
ActorLocation location;
|
||||
Location location;
|
||||
|
||||
objectNum = _vm->_scene->_objectMap->hitTest(imousePt);
|
||||
|
||||
@ -529,7 +531,7 @@ int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) {
|
||||
*/
|
||||
}
|
||||
|
||||
PanelButton *Interface::verbHitTest(const Point& imousePointer) {
|
||||
PanelButton *Interface::verbHitTest(const Point& mousePoint) {
|
||||
PanelButton *panelButton;
|
||||
Rect rect;
|
||||
int i;
|
||||
@ -540,7 +542,7 @@ PanelButton *Interface::verbHitTest(const Point& imousePointer) {
|
||||
rect.right = rect.left + panelButton->width;
|
||||
rect.top = _mainPanel.y + panelButton->yOffset;
|
||||
rect.bottom = rect.top + panelButton->height;
|
||||
if (rect.contains(imousePointer))
|
||||
if (rect.contains(mousePoint))
|
||||
return panelButton;
|
||||
}
|
||||
}
|
||||
@ -643,6 +645,7 @@ int Interface::inventoryTest(const Point& imousePt, int *ibutton) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
||||
void Interface::drawVerb(int verb, int state) {
|
||||
SURFACE *backBuffer;
|
||||
PanelButton * panelButton;
|
||||
|
@ -96,19 +96,18 @@ public:
|
||||
|
||||
int activate();
|
||||
int deactivate();
|
||||
bool isActive() { return _active; }
|
||||
int setMode(int mode, bool force = false);
|
||||
int getMode(void) const { return _panelMode; }
|
||||
void rememberMode();
|
||||
void restoreMode();
|
||||
void lockMode() { _lockedMode = _panelMode; }
|
||||
void unlockMode() { _panelMode = _lockedMode; }
|
||||
bool isInMainMode() { return _inMainMode; }
|
||||
int setStatusText(const char *new_txt);
|
||||
int loadScenePortraits(int resourceId);
|
||||
int setLeftPortrait(int portrait);
|
||||
int setRightPortrait(int portrait);
|
||||
int draw();
|
||||
int update(const Point& imousePointer, int updateFlag);
|
||||
int update(const Point& mousePoint, int updateFlag);
|
||||
int drawStatusBar(SURFACE *ds);
|
||||
void drawVerb(int verb, int state);
|
||||
|
||||
@ -120,12 +119,15 @@ public:
|
||||
|
||||
private:
|
||||
int inventoryTest(const Point& imousePt, int *ibutton);
|
||||
PanelButton *verbHitTest(const Point& imousePointer);
|
||||
void handleCommandUpdate(SURFACE *ds, const Point& imousePointer);
|
||||
void handleCommandClick(SURFACE *ds, const Point& imousePointer);
|
||||
PanelButton *verbHitTest(const Point& mousePoint);
|
||||
void handleCommandUpdate(SURFACE *ds, const Point& mousePoint);
|
||||
void handleCommandClick(SURFACE *ds, const Point& mousePoint);
|
||||
int handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt);
|
||||
int handlePlayfieldClick(SURFACE *ds, const Point& imousePt);
|
||||
|
||||
void lockMode() { _lockedMode = _panelMode; }
|
||||
void unlockMode() { _panelMode = _lockedMode; }
|
||||
|
||||
void drawPanelButtonText(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton, int textColor, int textShadowColor);
|
||||
public:
|
||||
void converseClear(void);
|
||||
@ -152,7 +154,7 @@ private:
|
||||
InterfacePanel _conversePanel;
|
||||
SpriteList _defPortraits;
|
||||
SpriteList _scenePortraits;
|
||||
SCRIPT_THREAD *_iThread;
|
||||
ScriptThread *_iThread;
|
||||
PanelButton *_verbTypeToPanelButton[kVerbTypesMax];
|
||||
|
||||
bool _active;
|
||||
@ -164,6 +166,8 @@ private:
|
||||
int _leftPortrait;
|
||||
int _rightPortrait;
|
||||
|
||||
Point _lastMousePoint;
|
||||
|
||||
uint16 *_inventory;
|
||||
int _inventorySize;
|
||||
byte _inventoryCount;
|
||||
|
@ -27,10 +27,6 @@
|
||||
|
||||
namespace Saga {
|
||||
|
||||
enum {
|
||||
kObjUseWith = 0x01,
|
||||
kObjNotFlat = 0x02
|
||||
};
|
||||
|
||||
OBJECTTABLE ObjectTable[OBJECTCOUNT] = {
|
||||
{ 8, 49, 1256, 760, 0, 9, 5, kObjNotFlat }, // Magic Hat
|
||||
|
@ -28,12 +28,17 @@
|
||||
|
||||
namespace Saga {
|
||||
|
||||
enum {
|
||||
kObjUseWith = 0x01,
|
||||
kObjNotFlat = 0x02
|
||||
};
|
||||
|
||||
struct OBJECTTABLE {
|
||||
byte nameIndex;
|
||||
int32 sceneIndex;
|
||||
int16 x, y, z;
|
||||
int32 spritelistRn;
|
||||
byte scriptRn;
|
||||
byte scriptEntrypointNumber;
|
||||
uint16 interactBits;
|
||||
};
|
||||
|
||||
|
@ -43,7 +43,7 @@ HitZone::HitZone(MemoryReadStreamEndian *readStream) {
|
||||
|
||||
_flags = readStream->readByte();
|
||||
_clickAreasCount = readStream->readByte();
|
||||
_defaultVerb = readStream->readByte();
|
||||
_rightButtonVerb = readStream->readByte();
|
||||
readStream->readByte(); // pad
|
||||
_nameNumber = readStream->readUint16();
|
||||
_scriptNumber = readStream->readUint16();
|
||||
|
@ -49,13 +49,16 @@ public:
|
||||
int getEntranceNumber() const {
|
||||
return _scriptNumber;
|
||||
}
|
||||
int getRightButtonVerb() const {
|
||||
return _rightButtonVerb;
|
||||
}
|
||||
|
||||
void draw(SURFACE *ds, int color);
|
||||
bool hitTest(const Point &testPoint);
|
||||
private:
|
||||
int _flags; // HitZoneFlags
|
||||
int _clickAreasCount;
|
||||
int _defaultVerb;
|
||||
int _rightButtonVerb;
|
||||
int _nameNumber;
|
||||
int _scriptNumber;
|
||||
|
||||
|
@ -115,6 +115,11 @@ namespace Saga {
|
||||
//TODO: fill it
|
||||
#define RID_SCENE1_VOICE_138 186
|
||||
|
||||
#define RID_BOAR_VOICE_000 239
|
||||
#define RID_BOAR_VOICE_002 241
|
||||
#define RID_BOAR_VOICE_005 244
|
||||
#define RID_BOAR_VOICE_006 245
|
||||
#define RID_BOAR_VOICE_007 246
|
||||
|
||||
// MUSIC
|
||||
#define MUSIC_1 9
|
||||
|
@ -357,6 +357,27 @@ const char *SagaEngine::getObjectName(uint16 objectId) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int SagaEngine::getObjectScriptEntrypointNumber(uint16 objectId) {
|
||||
ActorData *actor;
|
||||
switch (objectIdType(objectId)) {
|
||||
case kGameObjectActor:
|
||||
actor = _vm->_actor->getActor(objectId);
|
||||
return actor->scriptEntrypointNumber;
|
||||
break;
|
||||
}
|
||||
//todo: object name & etc
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SagaEngine::getObjectFlags(uint16 objectId) {
|
||||
ActorData *actor;
|
||||
if (objectIdType(objectId) == kGameObjectActor) {
|
||||
actor = _vm->_actor->getActor(objectId);
|
||||
return actor->flags;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *SagaEngine::getTextString(int textStringId) {
|
||||
const char *string;
|
||||
int lang = _vm->getFeatures() & GF_LANG_DE ? 1 : 0;
|
||||
@ -368,4 +389,30 @@ const char *SagaEngine::getTextString(int textStringId) {
|
||||
return string;
|
||||
}
|
||||
|
||||
void SagaEngine::getExcuseInfo(int verb, const char *&textString, int &soundResourceId) {
|
||||
textString = NULL; // TODO: i18n it !
|
||||
switch (verb) {
|
||||
case kVerbPickUp:
|
||||
textString = "I can't pick that up.";
|
||||
soundResourceId = RID_BOAR_VOICE_007;
|
||||
break;
|
||||
case kVerbLookAt:
|
||||
textString = "I see nothing special about it.";
|
||||
soundResourceId = RID_BOAR_VOICE_006;
|
||||
break;
|
||||
case kVerbOpen:
|
||||
textString = "There's no place to open it.";
|
||||
soundResourceId = RID_BOAR_VOICE_000;
|
||||
break;
|
||||
case kVerbClose:
|
||||
textString = "There's no opening to close.";
|
||||
soundResourceId = RID_BOAR_VOICE_002;
|
||||
break;
|
||||
case kVerbUse:
|
||||
textString = "I don't know how to do that.";
|
||||
soundResourceId = RID_BOAR_VOICE_005;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Saga
|
||||
|
@ -433,8 +433,10 @@ public:
|
||||
byte **output_buf, size_t *output_buf_len, int *w, int *h);
|
||||
const byte *getImagePal(const byte *image_data, size_t image_size);
|
||||
void loadStrings(StringsTable &stringsTable, const byte *stringsPointer, size_t stringsLength);
|
||||
const char *getObjectName(uint16 objectId);
|
||||
|
||||
const char *getObjectName(uint16 objectId);
|
||||
int getObjectScriptEntrypointNumber(uint16 objectId);
|
||||
int getObjectFlags(uint16 objectId);
|
||||
public:
|
||||
TEXTLIST *textCreateList();
|
||||
void textDestroyList(TEXTLIST *textlist);
|
||||
@ -491,6 +493,7 @@ public:
|
||||
const GameDisplayInfo & getDisplayInfo() { return _gameDisplayInfo; }
|
||||
|
||||
const char *getTextString(int textStringId);
|
||||
void getExcuseInfo(int verb, const char *&textString, int &soundResourceId);
|
||||
private:
|
||||
int loadGame(int gameNumber);
|
||||
};
|
||||
|
@ -191,7 +191,7 @@ int Scene::startScene() {
|
||||
scene_qdat = queueIterator.operator->();
|
||||
assert(scene_qdat != NULL);
|
||||
|
||||
loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->scene_desc, scene_qdat->fadeType);
|
||||
loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -230,7 +230,7 @@ int Scene::nextScene() {
|
||||
scene_qdat = queueIterator.operator->();
|
||||
assert(scene_qdat != NULL);
|
||||
|
||||
loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->scene_desc, scene_qdat->fadeType);
|
||||
loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -277,7 +277,7 @@ int Scene::skipScene() {
|
||||
_sceneQueue.erase(_sceneQueue.begin(), queueIterator);
|
||||
|
||||
endScene();
|
||||
loadScene(skip_qdat->scene_n, skip_qdat->load_flag, skip_qdat->scene_proc, skip_qdat->scene_desc, skip_qdat->fadeType);
|
||||
loadScene(skip_qdat->scene_n, skip_qdat->load_flag, skip_qdat->scene_proc, skip_qdat->sceneDescription, skip_qdat->fadeType);
|
||||
}
|
||||
// Search for a scene to skip to
|
||||
|
||||
@ -504,7 +504,7 @@ int Scene::getSceneLUT(int scene_num) {
|
||||
return _sceneLUT[scene_num];
|
||||
}
|
||||
|
||||
int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_DESC *scene_desc_param, int fadeType) {
|
||||
int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneDescription *scene_desc_param, int fadeType) {
|
||||
SCENE_INFO scene_info;
|
||||
uint32 res_number = 0;
|
||||
int result;
|
||||
@ -580,8 +580,8 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_
|
||||
}
|
||||
|
||||
// Load scene script data
|
||||
if (_desc.scriptNum > 0) {
|
||||
if (_vm->_script->loadScript(_desc.scriptNum) != SUCCESS) {
|
||||
if (_desc.scriptModuleNumber > 0) {
|
||||
if (_vm->_script->loadScript(_desc.scriptModuleNumber) != SUCCESS) {
|
||||
warning("Scene::loadScene(): Error loading scene script");
|
||||
return FAILURE;
|
||||
}
|
||||
@ -635,12 +635,12 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_
|
||||
q_event = _vm->_events->chain(q_event, &event);
|
||||
|
||||
// Start the scene pre script, but stay with black palette
|
||||
if (_desc.startScriptNum > 0) {
|
||||
if (_desc.startScriptEntrypointNumber > 0) {
|
||||
event.type = ONESHOT_EVENT;
|
||||
event.code = SCRIPT_EVENT;
|
||||
event.op = EVENT_EXEC_BLOCKING;
|
||||
event.time = 0;
|
||||
event.param = _desc.startScriptNum;
|
||||
event.param = _desc.startScriptEntrypointNumber;
|
||||
event.param2 = 0; // Action
|
||||
event.param3 = _sceneNumber; // Object
|
||||
event.param4 = 0; // With Object - TODO: should be 'entrance'
|
||||
@ -695,9 +695,9 @@ int Scene::loadSceneDescriptor(uint32 res_number) {
|
||||
_desc.resListRN = readS.readSint16();
|
||||
_desc.endSlope = readS.readSint16();
|
||||
_desc.beginSlope = readS.readSint16();
|
||||
_desc.scriptNum = readS.readUint16();
|
||||
_desc.sceneScriptNum = readS.readUint16();
|
||||
_desc.startScriptNum = readS.readUint16();
|
||||
_desc.scriptModuleNumber = readS.readUint16();
|
||||
_desc.sceneScriptEntrypointNumber = readS.readUint16();
|
||||
_desc.startScriptEntrypointNumber = readS.readUint16();
|
||||
_desc.musicRN = readS.readSint16();
|
||||
|
||||
RSC_FreeResource(scene_desc_data);
|
||||
@ -930,7 +930,7 @@ int Scene::endScene() {
|
||||
|
||||
_sceneProc(SCENE_END, &scene_info, this);
|
||||
|
||||
if (_desc.scriptNum > 0) {
|
||||
if (_desc.scriptModuleNumber > 0) {
|
||||
_vm->_script->freeScript();
|
||||
}
|
||||
|
||||
@ -1002,9 +1002,9 @@ void Scene::cmdSceneInfo() {
|
||||
_vm->_console->DebugPrintf(fmt, "Resource list R#:", _desc.resListRN);
|
||||
_vm->_console->DebugPrintf(fmt, "End slope:", _desc.endSlope);
|
||||
_vm->_console->DebugPrintf(fmt, "Begin slope:", _desc.beginSlope);
|
||||
_vm->_console->DebugPrintf(fmt, "Script resource:", _desc.scriptNum);
|
||||
_vm->_console->DebugPrintf(fmt, "Scene script:", _desc.sceneScriptNum);
|
||||
_vm->_console->DebugPrintf(fmt, "Start script:", _desc.startScriptNum);
|
||||
_vm->_console->DebugPrintf(fmt, "scriptModuleNumber:", _desc.scriptModuleNumber);
|
||||
_vm->_console->DebugPrintf(fmt, "sceneScriptEntrypointNumber:", _desc.sceneScriptEntrypointNumber);
|
||||
_vm->_console->DebugPrintf(fmt, "startScriptEntrypointNumber:", _desc.startScriptEntrypointNumber);
|
||||
_vm->_console->DebugPrintf(fmt, "Music R#", _desc.musicRN);
|
||||
}
|
||||
|
||||
@ -1084,12 +1084,12 @@ int Scene::defaultScene(int param, SCENE_INFO *scene_info) {
|
||||
_vm->_events->chain(q_event, &event);
|
||||
|
||||
// Start the scene main script
|
||||
if (_desc.sceneScriptNum > 0) {
|
||||
if (_desc.sceneScriptEntrypointNumber > 0) {
|
||||
event.type = ONESHOT_EVENT;
|
||||
event.code = SCRIPT_EVENT;
|
||||
event.op = EVENT_EXEC_NONBLOCKING;
|
||||
event.time = 0;
|
||||
event.param = _desc.sceneScriptNum;
|
||||
event.param = _desc.sceneScriptEntrypointNumber;
|
||||
event.param2 = 0; // Action
|
||||
event.param3 = _sceneNumber; // Object
|
||||
event.param4 = 0; // With Object - TODO: should be 'entrance'
|
||||
|
18
saga/scene.h
18
saga/scene.h
@ -99,14 +99,14 @@ struct SCENE_RESLIST {
|
||||
|
||||
#define SAGA_SCENE_DESC_LEN 16
|
||||
|
||||
struct SCENE_DESC {
|
||||
struct SceneDescription {
|
||||
int16 flags;
|
||||
int16 resListRN;
|
||||
int16 endSlope;
|
||||
int16 beginSlope;
|
||||
uint16 scriptNum;
|
||||
uint16 sceneScriptNum;
|
||||
uint16 startScriptNum;
|
||||
uint16 scriptModuleNumber;
|
||||
uint16 sceneScriptEntrypointNumber;
|
||||
uint16 startScriptEntrypointNumber;
|
||||
int16 musicRN;
|
||||
SCENE_RESLIST *resList;
|
||||
size_t resListCnt;
|
||||
@ -139,7 +139,7 @@ enum SCENE_FADE_TYPES {
|
||||
|
||||
struct SCENE_QUEUE {
|
||||
uint32 scene_n;
|
||||
SCENE_DESC *scene_desc;
|
||||
SceneDescription* sceneDescription;
|
||||
int load_flag;
|
||||
SCENE_PROC *scene_proc;
|
||||
int scene_skiptarget;
|
||||
@ -203,7 +203,8 @@ class Scene {
|
||||
int endScene();
|
||||
int queueScene(SCENE_QUEUE *scene_queue);
|
||||
int draw(SURFACE *);
|
||||
int getFlags() { return _desc.flags; }
|
||||
int getFlags() const { return _desc.flags; }
|
||||
int getScriptModuleNumber() const { return _desc.scriptModuleNumber; }
|
||||
bool isInDemo() { return !_inGame; }
|
||||
|
||||
void getBGMaskInfo(int &width, int &height, byte *&buffer, size_t &bufferLength);
|
||||
@ -232,8 +233,7 @@ class Scene {
|
||||
int currentSceneNumber() { return _sceneNumber; }
|
||||
|
||||
private:
|
||||
int loadScene(int scene, int load_flag, SCENE_PROC scene_proc, SCENE_DESC *,
|
||||
int fadeIn);
|
||||
int loadScene(int scene, int load_flag, SCENE_PROC scene_proc, SceneDescription *, int fadeIn);
|
||||
int loadSceneDescriptor(uint32 res_number);
|
||||
int loadSceneResourceList(uint32 res_number);
|
||||
int processSceneResources();
|
||||
@ -253,7 +253,7 @@ class Scene {
|
||||
int _sceneResNum;
|
||||
bool _inGame;
|
||||
bool _loadDesc;
|
||||
SCENE_DESC _desc;
|
||||
SceneDescription _desc;
|
||||
int _resListEntries;
|
||||
SCENE_RESLIST *_resList;
|
||||
int _animEntries;
|
||||
|
223
saga/script.cpp
223
saga/script.cpp
@ -31,6 +31,12 @@
|
||||
#include "saga/script.h"
|
||||
#include "saga/stream.h"
|
||||
#include "saga/interface.h"
|
||||
#include "saga/actordata.h"
|
||||
#include "saga/scene.h"
|
||||
#include "saga/events.h"
|
||||
#include "saga/actor.h"
|
||||
#include "saga/objectdata.h"
|
||||
#include "saga/objectmap.h"
|
||||
|
||||
namespace Saga {
|
||||
|
||||
@ -61,6 +67,7 @@ Script::Script() {
|
||||
_stickyVerb = kVerbWalkTo;
|
||||
_leftButtonVerb = kVerbNone;
|
||||
_rightButtonVerb = kVerbNone;
|
||||
_pointerObject = 0;
|
||||
|
||||
_dataBuf[0].data = _dataBuf[1].data = (ScriptDataWord *)calloc(SCRIPT_DATABUF_LEN, sizeof(ScriptDataWord));;
|
||||
_dataBuf[0].length = _dataBuf[1].length = SCRIPT_DATABUF_LEN;
|
||||
@ -256,7 +263,7 @@ int Script::getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState) {
|
||||
}
|
||||
|
||||
// Loads a script; including script bytecode and dialogue list
|
||||
int Script::loadScript(int script_num) {
|
||||
int Script::loadScript(int scriptModuleNumber) {
|
||||
ScriptData *script_data;
|
||||
byte *bytecode_p;
|
||||
size_t bytecode_len;
|
||||
@ -270,8 +277,8 @@ int Script::loadScript(int script_num) {
|
||||
int result;
|
||||
|
||||
// Validate script number
|
||||
if ((script_num < 0) || (script_num > _scriptLUTMax)) {
|
||||
warning("Script::loadScript(): Invalid script number");
|
||||
if ((scriptModuleNumber < 0) || (scriptModuleNumber > _scriptLUTMax)) {
|
||||
warning("Script::loadScript(): Invalid script module number");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@ -279,7 +286,7 @@ int Script::loadScript(int script_num) {
|
||||
freeScript();
|
||||
|
||||
// Initialize script data structure
|
||||
debug(0, "Loading script data for script #%d", script_num);
|
||||
debug(0, "Loading script data for script module #%d", scriptModuleNumber);
|
||||
|
||||
script_data = (ScriptData *)malloc(sizeof(*script_data));
|
||||
if (script_data == NULL) {
|
||||
@ -293,7 +300,7 @@ int Script::loadScript(int script_num) {
|
||||
script_data->voice = NULL;
|
||||
|
||||
// Load script bytecode
|
||||
scriptl_rn = _scriptLUT[script_num].script_rn;
|
||||
scriptl_rn = _scriptLUT[scriptModuleNumber].script_rn;
|
||||
|
||||
result = RSC_LoadResource(_scriptContext, scriptl_rn, &bytecode_p, &bytecode_len);
|
||||
if (result != SUCCESS) {
|
||||
@ -309,7 +316,7 @@ int Script::loadScript(int script_num) {
|
||||
}
|
||||
|
||||
// Load script strings list
|
||||
stringsResourceId = _scriptLUT[script_num].diag_list_rn;
|
||||
stringsResourceId = _scriptLUT[scriptModuleNumber].diag_list_rn;
|
||||
|
||||
// Load strings list resource
|
||||
result = RSC_LoadResource(_scriptContext, stringsResourceId, &stringsPointer, &stringsLength);
|
||||
@ -323,7 +330,7 @@ int Script::loadScript(int script_num) {
|
||||
|
||||
// Load voice resource lookup table
|
||||
if (_voiceLUTPresent) {
|
||||
voicelut_rn = _scriptLUT[script_num].voice_lut_rn;
|
||||
voicelut_rn = _scriptLUT[scriptModuleNumber].voice_lut_rn;
|
||||
|
||||
// Load voice LUT resource
|
||||
result = RSC_LoadResource(_scriptContext, voicelut_rn, &voicelut_p, &voicelut_len);
|
||||
@ -492,7 +499,7 @@ VOICE_LUT *Script::loadVoiceLUT(const byte *voicelut_p, size_t voicelut_len, Scr
|
||||
return voice_lut;
|
||||
}
|
||||
|
||||
void Script::scriptError(SCRIPT_THREAD *thread, const char *format, ...) {
|
||||
void Script::scriptError(ScriptThread *thread, const char *format, ...) {
|
||||
char buf[STRINGBUFLEN];
|
||||
va_list argptr;
|
||||
|
||||
@ -501,8 +508,8 @@ void Script::scriptError(SCRIPT_THREAD *thread, const char *format, ...) {
|
||||
va_end (argptr);
|
||||
|
||||
thread->flags |= kTFlagAborted;
|
||||
debug(0, "Script::scriptError %X: %s", thread->i_offset, buf);
|
||||
_vm->_console->DebugPrintf("Script::scriptError %X: %s", thread->i_offset, buf);
|
||||
debug(0, "Script::scriptError %X: %s", thread->instructionOffset, buf);
|
||||
_vm->_console->DebugPrintf("Script::scriptError %X: %s", thread->instructionOffset, buf);
|
||||
}
|
||||
|
||||
void Script::scriptInfo() {
|
||||
@ -536,7 +543,7 @@ void Script::scriptExec(int argc, const char **argv) {
|
||||
|
||||
if (_dbg_thread == NULL) {
|
||||
_vm->_console->DebugPrintf("Creating debug thread...\n");
|
||||
_dbg_thread = SThreadCreate();
|
||||
_dbg_thread = createThread();
|
||||
if (_dbg_thread == NULL) {
|
||||
_vm->_console->DebugPrintf("Thread creation failed.\n");
|
||||
return;
|
||||
@ -548,7 +555,7 @@ void Script::scriptExec(int argc, const char **argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
SThreadExecute(_dbg_thread, ep_num);
|
||||
executeThread(_dbg_thread, ep_num);
|
||||
}
|
||||
|
||||
// verb
|
||||
@ -641,6 +648,198 @@ void Script::setRightButtonVerb(int verb) {
|
||||
}
|
||||
|
||||
void Script::doVerb() {
|
||||
int scriptEntrypointNumber = 0;
|
||||
int scriptModuleNumber = 0;
|
||||
int objectType;
|
||||
EVENT event;
|
||||
const char *excuseText;
|
||||
int excuseSampleResourceId;
|
||||
|
||||
objectType = objectIdType(_pendingObject[0]);
|
||||
|
||||
if (_pendingVerb == kVerbGive) {
|
||||
scriptEntrypointNumber = _vm->getObjectScriptEntrypointNumber(_pendingObject[1]);
|
||||
if (_vm->getObjectFlags(_pendingObject[1]) & (kFollower|kProtagonist|kExtended)) {
|
||||
scriptModuleNumber = 0;
|
||||
} else {
|
||||
scriptModuleNumber = _vm->_scene->getScriptModuleNumber();
|
||||
}
|
||||
} else {
|
||||
if (_pendingVerb == kVerbUse) {
|
||||
if ((objectIdType(_pendingObject[1]) > kGameObjectNone) && (objectType < objectIdType(_pendingObject[1]))) {
|
||||
SWAP(_pendingObject[0], _pendingObject[1]);
|
||||
objectType = objectIdType(_pendingObject[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (objectType == kGameObjectHitZone) {
|
||||
scriptModuleNumber = _vm->_scene->getScriptModuleNumber();
|
||||
//TODO: check HitZone Exit
|
||||
} else {
|
||||
if (objectType & (kGameObjectActor | kGameObjectObject)) {
|
||||
scriptEntrypointNumber = _vm->getObjectScriptEntrypointNumber(_pendingObject[0]);
|
||||
|
||||
if ((objectType == kGameObjectActor) && !(_vm->getObjectFlags(_pendingObject[0]) & (kFollower|kProtagonist|kExtended))) {
|
||||
scriptModuleNumber = _vm->_scene->getScriptModuleNumber();
|
||||
} else {
|
||||
scriptModuleNumber = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptEntrypointNumber > 0) {
|
||||
if (scriptModuleNumber != _vm->_scene->getScriptModuleNumber()) {
|
||||
warning("scriptModuleNumber != _vm->_scene->getScriptModuleNumber()");
|
||||
}
|
||||
|
||||
event.type = ONESHOT_EVENT;
|
||||
event.code = SCRIPT_EVENT;
|
||||
event.op = EVENT_EXEC_NONBLOCKING;
|
||||
event.time = 0;
|
||||
event.param = scriptEntrypointNumber;
|
||||
event.param2 = _pendingVerb; // Action
|
||||
event.param3 = _pendingObject[0]; // Object
|
||||
event.param4 = _pendingObject[1]; // With Object
|
||||
event.param5 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor
|
||||
|
||||
_vm->_events->queue(&event);
|
||||
|
||||
} else {
|
||||
_vm->getExcuseInfo(_pendingVerb, excuseText, excuseSampleResourceId);
|
||||
if (excuseText)
|
||||
_vm->_actor->actorSpeech(ID_PROTAG, &excuseText, 1, excuseSampleResourceId, 0);
|
||||
}
|
||||
|
||||
if ((_currentVerb == kVerbWalkTo) || (_currentVerb == kVerbLookAt)) {
|
||||
_stickyVerb = _currentVerb;
|
||||
}
|
||||
|
||||
_pendingVerb = kVerbNone;
|
||||
_currentObject[0] = _currentObject[1] = ID_NOTHING;
|
||||
setLeftButtonVerb(_stickyVerb);
|
||||
|
||||
setPointerVerb();
|
||||
}
|
||||
|
||||
void Script::setPointerVerb() {
|
||||
Point mousePoint;
|
||||
mousePoint = _vm->getMousePos();
|
||||
if (_vm->_interface->isActive()) {
|
||||
_pointerObject = ID_PROTAG;
|
||||
whichObject(mousePoint);
|
||||
}
|
||||
}
|
||||
|
||||
void Script::whichObject(const Point& mousePointer) {
|
||||
uint16 objectId;
|
||||
int16 objectFlags;
|
||||
int newRightButtonVerb;
|
||||
uint16 newObjectId;
|
||||
ActorData *actor;
|
||||
Location pickLocation;
|
||||
int hitZoneId;
|
||||
HitZone * hitZone;
|
||||
|
||||
objectId = ID_NOTHING;
|
||||
objectFlags = 0;
|
||||
_leftButtonVerb = _currentVerb;
|
||||
newRightButtonVerb = kVerbNone;
|
||||
|
||||
if (_vm->_actor->_protagonist->currentAction == kActionWalkDir) {
|
||||
} else {
|
||||
newObjectId = _vm->_actor->testHit(mousePointer);
|
||||
|
||||
if (newObjectId != ID_NOTHING) {
|
||||
if (objectIdType(newObjectId) == kGameObjectObject) {
|
||||
objectId = newObjectId;
|
||||
objectFlags = 0;
|
||||
newRightButtonVerb = kVerbLookAt;
|
||||
|
||||
if ((_currentVerb == kVerbTalkTo) || ((_currentVerb == kVerbGive) && _firstObjectSet)) {
|
||||
objectId = ID_NOTHING;
|
||||
newObjectId = ID_NOTHING;
|
||||
}
|
||||
} else {
|
||||
actor = _vm->_actor->getActor(newObjectId);
|
||||
objectId = newObjectId;
|
||||
objectFlags = kObjUseWith;
|
||||
newRightButtonVerb = kVerbTalkTo;
|
||||
|
||||
if ((_currentVerb == kVerbPickUp) ||
|
||||
(_currentVerb == kVerbOpen) ||
|
||||
(_currentVerb == kVerbClose) ||
|
||||
((_currentVerb == kVerbGive) && !_firstObjectSet) ||
|
||||
((_currentVerb == kVerbUse) && !(actor->flags & kFollower))) {
|
||||
objectId = ID_NOTHING;
|
||||
newObjectId = ID_NOTHING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newObjectId == ID_NOTHING) {
|
||||
/* struct HitZone far *newZone = NULL;
|
||||
UWORD zone;*/
|
||||
|
||||
|
||||
if (_vm->_scene->getFlags() & kSceneFlagISO) {
|
||||
//todo: it
|
||||
} else {
|
||||
pickLocation.x = mousePointer.x;
|
||||
pickLocation.y = mousePointer.y;
|
||||
pickLocation.z = 0;
|
||||
}
|
||||
|
||||
hitZoneId = _vm->_scene->_objectMap->hitTest(mousePointer);
|
||||
|
||||
if ((hitZoneId != -1) && 0) { //TODO: do it
|
||||
//hitZone = _vm->_scene->_objectMap->getZone(hitZoneId);
|
||||
//objectId = hitZone->objectId;
|
||||
objectFlags = 0;
|
||||
newRightButtonVerb = hitZone->getRightButtonVerb() & 0x7f;
|
||||
|
||||
if (newRightButtonVerb == kVerbWalkOnly) {
|
||||
if (_firstObjectSet) {
|
||||
objectId = ID_NOTHING;
|
||||
} else {
|
||||
newRightButtonVerb = _leftButtonVerb = kVerbWalkTo;
|
||||
}
|
||||
} else {
|
||||
if (_firstObjectSet) {
|
||||
objectId = ID_NOTHING;
|
||||
} else {
|
||||
newRightButtonVerb = _leftButtonVerb = kVerbLookAt;
|
||||
}
|
||||
}
|
||||
|
||||
if (newRightButtonVerb >= kVerbOptions) {
|
||||
newRightButtonVerb = kVerbNone;
|
||||
}
|
||||
|
||||
if ((_currentVerb == kVerbTalkTo) || ((_currentVerb == kVerbGive) && !_firstObjectSet)) {
|
||||
objectId = ID_NOTHING;
|
||||
newObjectId = ID_NOTHING;
|
||||
}
|
||||
|
||||
if ((_leftButtonVerb == kVerbUse) && (hitZone->getRightButtonVerb() & 0x80)) {
|
||||
objectFlags = kObjUseWith;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (objectId != _pointerObject) {
|
||||
_pointerObject = objectId;
|
||||
_currentObject[_firstObjectSet ? 1 : 0] = objectId;
|
||||
_currentObjectFlags[_firstObjectSet ? 1 : 0] = objectFlags;
|
||||
if (_pendingVerb == kVerbNone) {
|
||||
showVerb();
|
||||
}
|
||||
}
|
||||
|
||||
if (newRightButtonVerb != _rightButtonVerb) {
|
||||
setRightButtonVerb(newRightButtonVerb);
|
||||
}
|
||||
}
|
||||
|
||||
// console wrappers
|
||||
|
@ -127,15 +127,15 @@ enum WalkFlags {
|
||||
kWalkFace = (1<<5)
|
||||
};
|
||||
|
||||
struct SCRIPT_THREAD {
|
||||
struct ScriptThread {
|
||||
int flags; // ThreadFlags
|
||||
int waitType; // ThreadWaitTypes
|
||||
void *threadObj; // which object we're handling
|
||||
|
||||
uint sleepTime;
|
||||
int ep_num; // Entrypoint number
|
||||
unsigned long ep_offset; // Entrypoint offset
|
||||
unsigned long i_offset; // Instruction offset
|
||||
int entrypointNumber; // Entrypoint number
|
||||
unsigned long entrypointOffset; // Entrypoint offset
|
||||
unsigned long instructionOffset; // Instruction offset
|
||||
|
||||
// The scripts are allowed to access the stack like any other memory
|
||||
// area. It's therefore probably quite important that our stacks work
|
||||
@ -183,10 +183,12 @@ struct SCRIPT_THREAD {
|
||||
sleepTime = aSleepTime;
|
||||
}
|
||||
|
||||
SCRIPT_THREAD() { memset(this, 0, sizeof(*this)); }
|
||||
ScriptThread() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
};
|
||||
|
||||
typedef SortedList<SCRIPT_THREAD> ScriptThreadList;
|
||||
typedef SortedList<ScriptThread> ScriptThreadList;
|
||||
|
||||
struct PROC_TBLENTRY {
|
||||
size_t name_offset;
|
||||
@ -224,7 +226,7 @@ struct ScriptDataBuf {
|
||||
int length;
|
||||
};
|
||||
|
||||
#define SCRIPTFUNC_PARAMS SCRIPT_THREAD *thread, int nArgs
|
||||
#define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs
|
||||
|
||||
class Script {
|
||||
public:
|
||||
@ -251,11 +253,19 @@ public:
|
||||
void doVerb();
|
||||
void showVerb();
|
||||
void setVerb(int verb);
|
||||
void setLeftButtonVerb(int verb);
|
||||
void setRightButtonVerb(int verb);
|
||||
int getCurrentVerb() const { return _currentVerb; }
|
||||
void setPointerVerb();
|
||||
void whichObject(const Point& mousePointer);
|
||||
|
||||
void setLeftButtonVerb(int verb);
|
||||
int getLeftButtonVerb() const { return _leftButtonVerb; }
|
||||
void setRightButtonVerb(int verb);
|
||||
int getRightButtonVerb() const { return _rightButtonVerb; }
|
||||
void setNonPlayfieldVerb() {
|
||||
setRightButtonVerb(kVerbNone);
|
||||
_pointerObject = ID_NOTHING;
|
||||
_currentObject[_firstObjectSet ? 1 : 0] = ID_NOTHING;
|
||||
}
|
||||
|
||||
void scriptInfo();
|
||||
void scriptExec(int argc, const char **argv);
|
||||
@ -276,13 +286,15 @@ protected:
|
||||
bool _firstObjectSet;
|
||||
bool _secondObjectNeeded;
|
||||
uint16 _currentObject[2];
|
||||
int16 _currentObjectFlags[2];
|
||||
uint16 _pendingObject[2];
|
||||
int _currentVerb;
|
||||
int _stickyVerb;
|
||||
int _leftButtonVerb;
|
||||
int _rightButtonVerb;
|
||||
int _pendingVerb;
|
||||
|
||||
|
||||
uint16 _pointerObject;
|
||||
|
||||
public:
|
||||
bool _skipSpeeches;
|
||||
@ -290,27 +302,27 @@ public:
|
||||
|
||||
int _dbg_singlestep;
|
||||
int _dbg_dostep;
|
||||
SCRIPT_THREAD *_dbg_thread;
|
||||
ScriptThread *_dbg_thread;
|
||||
TEXTLIST_ENTRY *_dbg_txtentry;
|
||||
|
||||
public:
|
||||
SCRIPT_THREAD *SThreadCreate();
|
||||
int SThreadExecute(SCRIPT_THREAD *thread, int ep_num);
|
||||
ScriptThread *createThread();
|
||||
int executeThread(ScriptThread *thread, int entrypointNumber);
|
||||
int executeThreads(uint msec);
|
||||
int SThreadDebugStep();
|
||||
void SThreadCompleteThread(void);
|
||||
void completeThread(void);
|
||||
|
||||
void wakeUpActorThread(int waitType, void *threadObj);
|
||||
void wakeUpThreads(int waitType);
|
||||
void wakeUpThreadsDelayed(int waitType, int sleepTime);
|
||||
|
||||
private:
|
||||
void setFramePtr(SCRIPT_THREAD *thread, int newPtr);
|
||||
unsigned char *SThreadGetReadPtr(SCRIPT_THREAD *thread);
|
||||
void setFramePtr(ScriptThread *thread, int newPtr);
|
||||
unsigned char *SThreadGetReadPtr(ScriptThread *thread);
|
||||
unsigned long SThreadGetReadOffset(const byte *read_p);
|
||||
size_t SThreadGetReadLen(SCRIPT_THREAD *thread);
|
||||
void runThread(SCRIPT_THREAD *thread, int instr_limit);
|
||||
int SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num);
|
||||
size_t SThreadGetReadLen(ScriptThread *thread);
|
||||
void runThread(ScriptThread *thread, int instr_limit);
|
||||
void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber);
|
||||
|
||||
private:
|
||||
typedef int (Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS);
|
||||
@ -322,8 +334,8 @@ private:
|
||||
const ScriptFunctionDescription *_scriptFunctionsList;
|
||||
|
||||
void setupScriptFuncList(void);
|
||||
void scriptError(SCRIPT_THREAD *thread, const char *format, ...);
|
||||
int SDebugPrintInstr(SCRIPT_THREAD *thread);
|
||||
void scriptError(ScriptThread *thread, const char *format, ...);
|
||||
int SDebugPrintInstr(ScriptThread *thread);
|
||||
|
||||
int SF_putString(SCRIPTFUNC_PARAMS);
|
||||
int sfWait(SCRIPTFUNC_PARAMS);
|
||||
|
@ -37,7 +37,7 @@ namespace Saga {
|
||||
#define SD_DISPLAY_LEN 128
|
||||
#define SD_ADDTXT(x) strncat(disp_buf, x, SD_DISPLAY_LEN);
|
||||
|
||||
int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
|
||||
int Script::SDebugPrintInstr(ScriptThread *thread) {
|
||||
TEXTLIST_ENTRY tl_e;
|
||||
char tmp_buf[80] = { 0 };
|
||||
static char disp_buf[SD_DISPLAY_LEN] = { 0 };
|
||||
@ -66,11 +66,11 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
|
||||
tl_e.display = 1;
|
||||
|
||||
MemoryReadStream readS(currentScript()->bytecode->bytecode_p
|
||||
+ thread->i_offset,
|
||||
+ thread->instructionOffset,
|
||||
currentScript()->bytecode->bytecode_len
|
||||
- thread->i_offset);
|
||||
- thread->instructionOffset);
|
||||
in_char = readS.readByte();
|
||||
sprintf(tmp_buf, "%04lX | %02X | ", thread->i_offset, in_char);
|
||||
sprintf(tmp_buf, "%04lX | %02X | ", thread->instructionOffset, in_char);
|
||||
strncat(disp_buf, tmp_buf, SD_DISPLAY_LEN);
|
||||
|
||||
switch (in_char) {
|
||||
|
@ -209,7 +209,7 @@ int Script::SF_mainMode(SCRIPTFUNC_PARAMS) {
|
||||
// Param3: actor y
|
||||
int Script::sfScriptWalkTo(SCRIPTFUNC_PARAMS) {
|
||||
uint16 actorId;
|
||||
ActorLocation actorLocation;
|
||||
Location actorLocation;
|
||||
ActorData *actor;
|
||||
|
||||
actorId = getSWord(thread->pop());
|
||||
@ -566,7 +566,7 @@ int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
|
||||
// Param3: actor y
|
||||
int Script::sfScriptWalkToAsync(SCRIPTFUNC_PARAMS) {
|
||||
uint16 actorId;
|
||||
ActorLocation actorLocation;
|
||||
Location actorLocation;
|
||||
ActorData *actor;
|
||||
|
||||
actorId = getSWord(thread->pop());
|
||||
@ -619,7 +619,7 @@ int Script::sfSetActorState(SCRIPTFUNC_PARAMS) {
|
||||
// Param3: actor pos y
|
||||
int Script::scriptMoveTo(SCRIPTFUNC_PARAMS) {
|
||||
uint16 actorId;
|
||||
ActorLocation actorLocation;
|
||||
Location actorLocation;
|
||||
ActorData *actor;
|
||||
|
||||
actorId = getSWord(thread->pop());
|
||||
@ -688,7 +688,7 @@ int Script::sfSwapActors(SCRIPTFUNC_PARAMS) {
|
||||
uint16 actorId2;
|
||||
ActorData *actor1;
|
||||
ActorData *actor2;
|
||||
ActorLocation location;
|
||||
Location location;
|
||||
|
||||
actorId1 = getSWord(thread->pop());
|
||||
actorId2 = getSWord(thread->pop());
|
||||
@ -751,7 +751,7 @@ int Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {
|
||||
// Param4: actor walk flag
|
||||
int Script::sfScriptWalk(SCRIPTFUNC_PARAMS) {
|
||||
uint16 actorId;
|
||||
ActorLocation actorLocation;
|
||||
Location actorLocation;
|
||||
ActorData *actor;
|
||||
uint16 walkFlags;
|
||||
|
||||
@ -917,7 +917,7 @@ int Script::SF_scriptSpecialWalk(SCRIPTFUNC_PARAMS) {
|
||||
// Param6: actor frame number
|
||||
int Script::sfPlaceActor(SCRIPTFUNC_PARAMS) {
|
||||
uint16 actorId;
|
||||
ActorLocation actorLocation;
|
||||
Location actorLocation;
|
||||
int actorDirection;
|
||||
int frameType;
|
||||
int frameOffset;
|
||||
|
106
saga/sthread.cpp
106
saga/sthread.cpp
@ -37,34 +37,34 @@
|
||||
|
||||
namespace Saga {
|
||||
|
||||
void Script::setFramePtr(SCRIPT_THREAD *thread, int newPtr) {
|
||||
void Script::setFramePtr(ScriptThread *thread, int newPtr) {
|
||||
thread->framePtr = newPtr;
|
||||
dataBuffer(3)->length = ARRAYSIZE(thread->stackBuf) - thread->framePtr;
|
||||
dataBuffer(3)->data = (ScriptDataWord *) &(thread->stackBuf[newPtr]);
|
||||
}
|
||||
|
||||
SCRIPT_THREAD *Script::SThreadCreate() {
|
||||
SCRIPT_THREAD *new_thread;
|
||||
ScriptThread *Script::createThread() {
|
||||
ScriptThread *newThread;
|
||||
|
||||
if (!isInitialized()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_thread = _threadList.pushFront().operator->();
|
||||
newThread = _threadList.pushFront().operator->();
|
||||
|
||||
new_thread->stackPtr = ARRAYSIZE(new_thread->stackBuf) - 1;
|
||||
setFramePtr(new_thread, new_thread->stackPtr);
|
||||
newThread->stackPtr = ARRAYSIZE(newThread->stackBuf) - 1;
|
||||
setFramePtr(newThread, newThread->stackPtr);
|
||||
|
||||
new_thread->flags = kTFlagWaiting;
|
||||
new_thread->waitType = kWaitTypePause;
|
||||
newThread->flags = kTFlagWaiting;
|
||||
newThread->waitType = kWaitTypePause;
|
||||
|
||||
dataBuffer(4)->length = ARRAYSIZE(new_thread->threadVars);
|
||||
dataBuffer(4)->data = new_thread->threadVars;
|
||||
return new_thread;
|
||||
dataBuffer(4)->length = ARRAYSIZE(newThread->threadVars);
|
||||
dataBuffer(4)->data = newThread->threadVars;
|
||||
return newThread;
|
||||
}
|
||||
|
||||
void Script::wakeUpActorThread(int waitType, void *threadObj) {
|
||||
SCRIPT_THREAD *thread;
|
||||
ScriptThread *thread;
|
||||
ScriptThreadList::iterator threadIterator;
|
||||
|
||||
for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) {
|
||||
@ -76,7 +76,7 @@ void Script::wakeUpActorThread(int waitType, void *threadObj) {
|
||||
}
|
||||
|
||||
void Script::wakeUpThreads(int waitType) {
|
||||
SCRIPT_THREAD *thread;
|
||||
ScriptThread *thread;
|
||||
ScriptThreadList::iterator threadIterator;
|
||||
|
||||
for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) {
|
||||
@ -88,7 +88,7 @@ void Script::wakeUpThreads(int waitType) {
|
||||
}
|
||||
|
||||
void Script::wakeUpThreadsDelayed(int waitType, int sleepTime) {
|
||||
SCRIPT_THREAD *thread;
|
||||
ScriptThread *thread;
|
||||
ScriptThreadList::iterator threadIterator;
|
||||
|
||||
for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) {
|
||||
@ -101,7 +101,7 @@ void Script::wakeUpThreadsDelayed(int waitType, int sleepTime) {
|
||||
}
|
||||
|
||||
int Script::executeThreads(uint msec) {
|
||||
SCRIPT_THREAD *thread;
|
||||
ScriptThread *thread;
|
||||
ScriptThreadList::iterator threadIterator;
|
||||
|
||||
if (!isInitialized()) {
|
||||
@ -114,8 +114,8 @@ int Script::executeThreads(uint msec) {
|
||||
thread = threadIterator.operator->();
|
||||
|
||||
if (thread->flags & (kTFlagFinished | kTFlagAborted)) {
|
||||
//if (thread->flags & kTFlagFinished) // FIXME. Missing function
|
||||
|
||||
if (thread->flags & kTFlagFinished)
|
||||
setPointerVerb();
|
||||
|
||||
threadIterator = _threadList.erase(threadIterator);
|
||||
continue;
|
||||
@ -152,12 +152,12 @@ int Script::executeThreads(uint msec) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void Script::SThreadCompleteThread(void) {
|
||||
void Script::completeThread(void) {
|
||||
for (int i = 0; i < 40 && !_threadList.isEmpty() ; i++)
|
||||
executeThreads(0);
|
||||
}
|
||||
|
||||
int Script::SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num) {
|
||||
void Script::setThreadEntrypoint(ScriptThread *thread, int entrypointNumber) {
|
||||
SCRIPT_BYTECODE *bytecode;
|
||||
int max_entrypoint;
|
||||
|
||||
@ -166,26 +166,24 @@ int Script::SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num) {
|
||||
bytecode = currentScript()->bytecode;
|
||||
max_entrypoint = bytecode->n_entrypoints;
|
||||
|
||||
if ((ep_num < 0) || (ep_num >= max_entrypoint)) {
|
||||
return FAILURE;
|
||||
if ((entrypointNumber < 0) || (entrypointNumber >= max_entrypoint)) {
|
||||
error("Script::setThreadEntrypoint wrong entrypointNumber");
|
||||
}
|
||||
|
||||
thread->ep_num = ep_num;
|
||||
thread->ep_offset = bytecode->entrypoints[ep_num].offset;
|
||||
|
||||
return SUCCESS;
|
||||
thread->entrypointNumber = entrypointNumber;
|
||||
thread->entrypointOffset = bytecode->entrypoints[entrypointNumber].offset;
|
||||
}
|
||||
|
||||
int Script::SThreadExecute(SCRIPT_THREAD *thread, int ep_num) {
|
||||
int Script::executeThread(ScriptThread *thread, int entrypointNumber) {
|
||||
assert(isInitialized());
|
||||
|
||||
if ((currentScript() == NULL) || (!currentScript()->loaded)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
SThreadSetEntrypoint(thread, ep_num);
|
||||
setThreadEntrypoint(thread, entrypointNumber);
|
||||
|
||||
thread->i_offset = thread->ep_offset;
|
||||
thread->instructionOffset = thread->entrypointOffset;
|
||||
thread->flags = kTFlagNone;
|
||||
|
||||
return SUCCESS;
|
||||
@ -193,16 +191,16 @@ int Script::SThreadExecute(SCRIPT_THREAD *thread, int ep_num) {
|
||||
|
||||
|
||||
|
||||
unsigned char *Script::SThreadGetReadPtr(SCRIPT_THREAD *thread) {
|
||||
return currentScript()->bytecode->bytecode_p + thread->i_offset;
|
||||
unsigned char *Script::SThreadGetReadPtr(ScriptThread *thread) {
|
||||
return currentScript()->bytecode->bytecode_p + thread->instructionOffset;
|
||||
}
|
||||
|
||||
unsigned long Script::SThreadGetReadOffset(const byte *read_p) {
|
||||
return (unsigned long)(read_p - (unsigned char *)currentScript()->bytecode->bytecode_p);
|
||||
}
|
||||
|
||||
size_t Script::SThreadGetReadLen(SCRIPT_THREAD *thread) {
|
||||
return currentScript()->bytecode->bytecode_len - thread->i_offset;
|
||||
size_t Script::SThreadGetReadLen(ScriptThread *thread) {
|
||||
return currentScript()->bytecode->bytecode_len - thread->instructionOffset;
|
||||
}
|
||||
|
||||
|
||||
@ -216,7 +214,7 @@ int Script::SThreadDebugStep() {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
void Script::runThread(ScriptThread *thread, int instr_limit) {
|
||||
int instr_count;
|
||||
uint32 saved_offset;
|
||||
ScriptDataWord param1;
|
||||
@ -251,23 +249,23 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
dataBuffer(2)->length = currentScript()->bytecode->bytecode_len / sizeof(ScriptDataWord);
|
||||
dataBuffer(2)->data = (ScriptDataWord *) currentScript()->bytecode->bytecode_p;
|
||||
|
||||
scriptS.seek(thread->i_offset);
|
||||
scriptS.seek(thread->instructionOffset);
|
||||
|
||||
for (instr_count = 0; instr_count < instr_limit; instr_count++) {
|
||||
if (thread->flags & (kTFlagAsleep))
|
||||
break;
|
||||
|
||||
saved_offset = thread->i_offset;
|
||||
saved_offset = thread->instructionOffset;
|
||||
operandChar = scriptS.readByte();
|
||||
// debug print (opCode name etc) should be placed here
|
||||
// SDebugPrintInstr(thread)
|
||||
|
||||
// debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->i_offset, operandChar, thread->stackSize());
|
||||
// debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->instructionOffset, operandChar, thread->stackSize());
|
||||
switch (operandChar) {
|
||||
case 0x01: // nextblock
|
||||
// Some sort of "jump to the start of the next memory
|
||||
// page" instruction, I think.
|
||||
thread->i_offset = 1024 * ((thread->i_offset / 1024) + 1);
|
||||
thread->instructionOffset = 1024 * ((thread->instructionOffset / 1024) + 1);
|
||||
break;
|
||||
|
||||
// STACK INSTRUCTIONS
|
||||
@ -356,7 +354,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
// counter as a pointer here. But I don't think
|
||||
// we will have to do that.
|
||||
thread->push(data);
|
||||
thread->i_offset = (unsigned long)param1;
|
||||
thread->instructionOffset = (unsigned long)param1;
|
||||
}
|
||||
break;
|
||||
case opCcall: // Call function
|
||||
@ -377,7 +375,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
scriptFunction = _scriptFunctionsList[functionNumber].scriptFunction;
|
||||
scriptFunctionReturnValue = (this->*scriptFunction)(thread, argumentsCount);
|
||||
if (scriptFunctionReturnValue != SUCCESS) {
|
||||
_vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->i_offset, scriptFunctionReturnValue);
|
||||
_vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->instructionOffset, scriptFunctionReturnValue);
|
||||
}
|
||||
|
||||
if (functionNumber == 16) { // SF_gotoScene
|
||||
@ -408,7 +406,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
thread->flags |= kTFlagFinished;
|
||||
return;
|
||||
} else {
|
||||
thread->i_offset = thread->pop();
|
||||
thread->instructionOffset = thread->pop();
|
||||
/* int n_args = */ thread->pop();
|
||||
if (operandChar == opReturn)
|
||||
thread->push(scriptRetVal);
|
||||
@ -420,14 +418,14 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
// (JMP): Unconditional jump
|
||||
case 0x1D:
|
||||
param1 = scriptS.readUint16LE();
|
||||
thread->i_offset = (unsigned long)param1;
|
||||
thread->instructionOffset = (unsigned long)param1;
|
||||
break;
|
||||
// (JNZP): Jump if nonzero + POP
|
||||
case 0x1E:
|
||||
param1 = scriptS.readUint16LE();
|
||||
data = thread->pop();
|
||||
if (data) {
|
||||
thread->i_offset = (unsigned long)param1;
|
||||
thread->instructionOffset = (unsigned long)param1;
|
||||
}
|
||||
break;
|
||||
// (JZP): Jump if zero + POP
|
||||
@ -435,7 +433,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
param1 = scriptS.readUint16LE();
|
||||
data = thread->pop();
|
||||
if (!data) {
|
||||
thread->i_offset = (unsigned long)param1;
|
||||
thread->instructionOffset = (unsigned long)param1;
|
||||
}
|
||||
break;
|
||||
// (JNZ): Jump if nonzero
|
||||
@ -443,7 +441,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
param1 = scriptS.readUint16LE();
|
||||
data = thread->stackTop();
|
||||
if (data) {
|
||||
thread->i_offset = (unsigned long)param1;
|
||||
thread->instructionOffset = (unsigned long)param1;
|
||||
}
|
||||
break;
|
||||
// (JZ): Jump if zero
|
||||
@ -451,7 +449,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
param1 = scriptS.readUint16LE();
|
||||
data = thread->stackTop();
|
||||
if (!data) {
|
||||
thread->i_offset = (unsigned long)param1;
|
||||
thread->instructionOffset = (unsigned long)param1;
|
||||
}
|
||||
break;
|
||||
// (SWCH): Switch
|
||||
@ -470,7 +468,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
switch_jmp = scriptS.readUint16LE();
|
||||
// Found the specified case
|
||||
if (data == (ScriptDataWord) switch_num) {
|
||||
thread->i_offset = switch_jmp;
|
||||
thread->instructionOffset = switch_jmp;
|
||||
case_found = 1;
|
||||
break;
|
||||
}
|
||||
@ -479,7 +477,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
// Jump to default case
|
||||
if (!case_found) {
|
||||
default_jmp = scriptS.readUint16LE();
|
||||
thread->i_offset = default_jmp;
|
||||
thread->instructionOffset = default_jmp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -497,7 +495,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
uint16 offset = scriptS.readUint16LE();
|
||||
|
||||
if (branch_probability > probability) {
|
||||
thread->i_offset = offset;
|
||||
thread->instructionOffset = offset;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -770,7 +768,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
|
||||
if (!(speechFlags & kSpeakAsync)) {
|
||||
thread->wait(kWaitTypeSpeech);
|
||||
thread->i_offset = scriptS.pos();
|
||||
thread->instructionOffset = scriptS.pos();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -803,7 +801,7 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
scriptS.readUint16LE();
|
||||
scriptS.readUint16LE();
|
||||
iparam1 = (long)scriptS.readByte();
|
||||
thread->i_offset += iparam1;
|
||||
thread->instructionOffset += iparam1;
|
||||
break;
|
||||
|
||||
// End instruction list
|
||||
@ -814,14 +812,14 @@ void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
|
||||
}
|
||||
|
||||
// Set instruction offset only if a previous instruction didn't branch
|
||||
if (saved_offset == thread->i_offset) {
|
||||
thread->i_offset = scriptS.pos();
|
||||
if (saved_offset == thread->instructionOffset) {
|
||||
thread->instructionOffset = scriptS.pos();
|
||||
} else {
|
||||
if (thread->i_offset >= scriptS.size()) {
|
||||
if (thread->instructionOffset >= scriptS.size()) {
|
||||
scriptError(thread, "Out of range script execution");
|
||||
return;
|
||||
} else {
|
||||
scriptS.seek(thread->i_offset);
|
||||
scriptS.seek(thread->instructionOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,9 +60,9 @@ Scene.c
|
||||
resInfo->loadList _desc.resListRN
|
||||
resInfo->horizon _desc.endSlope
|
||||
resInfo->nearFigureLimit _desc.beginSlope
|
||||
resInfo->scriptModule _desc.scriptNum
|
||||
resInfo->entryScript _desc.sceneScriptNum
|
||||
resInfo->preScript _desc.startScriptNum
|
||||
resInfo->scriptModule _desc.scriptModuleNumber
|
||||
resInfo->entryScript _desc.sceneScriptEntrypointNumber
|
||||
resInfo->preScript _desc.startScriptEntrypointNumber
|
||||
resInfo->backgroundMusic _desc.musicRN
|
||||
thisScene->ID currentSceneNumber()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user