mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
MUTATIONOFJB: Improve documentation, rename cryptic variables.
This commit is contained in:
committed by
Eugene Sandulenko
parent
cda1f0dd3a
commit
578a6794de
@@ -381,22 +381,22 @@ Command::ExecuteResult ChangeObjectCommand::execute(ScriptExecutionContext &scri
|
|||||||
|
|
||||||
switch (_register) {
|
switch (_register) {
|
||||||
case AC:
|
case AC:
|
||||||
object->_AC = _value._byteVal;
|
object->_active = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case FA:
|
case FA:
|
||||||
object->_FA = _value._byteVal;
|
object->_firstFrame = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case FR:
|
case FR:
|
||||||
object->_FR = _value._byteVal;
|
object->_randomFrame = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case NA:
|
case NA:
|
||||||
object->_NA = _value._byteVal;
|
object->_numFrames = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case FS:
|
case FS:
|
||||||
object->_FS = _value._byteVal;
|
object->_roomFrameLSB = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case CA:
|
case CA:
|
||||||
object->_CA = _value._byteVal;
|
object->_currentFrame = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case XX:
|
case XX:
|
||||||
object->_x = _value._wordVal;
|
object->_x = _value._wordVal;
|
||||||
@@ -405,16 +405,16 @@ Command::ExecuteResult ChangeObjectCommand::execute(ScriptExecutionContext &scri
|
|||||||
object->_y = _value._byteVal;
|
object->_y = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case XL:
|
case XL:
|
||||||
object->_XL = _value._wordVal;
|
object->_width = _value._wordVal;
|
||||||
break;
|
break;
|
||||||
case YL:
|
case YL:
|
||||||
object->_YL = _value._byteVal;
|
object->_height = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case WX:
|
case WX:
|
||||||
object->_WX = _value._wordVal;
|
object->_WX = _value._wordVal;
|
||||||
break;
|
break;
|
||||||
case WY:
|
case WY:
|
||||||
object->_WY = _value._byteVal;
|
object->_roomFrameMSB = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case SP:
|
case SP:
|
||||||
object->_SP = _value._byteVal;
|
object->_SP = _value._byteVal;
|
||||||
@@ -468,7 +468,7 @@ Command::ExecuteResult ChangeStaticCommand::execute(ScriptExecutionContext &scri
|
|||||||
stat->_walkToY = _value._byteVal;
|
stat->_walkToY = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case SP:
|
case SP:
|
||||||
stat->_SP = _value._byteVal;
|
stat->_walkToFrame = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warning("Object does not support changing this register.");
|
warning("Object does not support changing this register.");
|
||||||
@@ -493,7 +493,7 @@ Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scrip
|
|||||||
scene->_startup = _value._byteVal;
|
scene->_startup = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case DL:
|
case DL:
|
||||||
scene->_DL = _value._byteVal;
|
scene->_delay = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case ND:
|
case ND:
|
||||||
scene->_noDoors = _value._byteVal;
|
scene->_noDoors = _value._byteVal;
|
||||||
@@ -505,13 +505,13 @@ Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scrip
|
|||||||
scene->_noStatics = _value._byteVal;
|
scene->_noStatics = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case PF:
|
case PF:
|
||||||
scene->_palRotStart = _value._byteVal;
|
scene->_palRotFirst = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case PL:
|
case PL:
|
||||||
scene->_palRotEnd = _value._byteVal;
|
scene->_palRotLast = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
case PD:
|
case PD:
|
||||||
scene->_palRotPeriod = _value._byteVal;
|
scene->_palRotDelay = _value._byteVal;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warning("Scene does not support changing this register.");
|
warning("Scene does not support changing this register.");
|
||||||
|
|||||||
@@ -318,14 +318,14 @@ bool Console::cmd_dumpsceneinfo(int argc, const char **argv) {
|
|||||||
Scene *scene = _vm->getGame().getGameData().getScene(sceneId);
|
Scene *scene = _vm->getGame().getGameData().getScene(sceneId);
|
||||||
if (scene) {
|
if (scene) {
|
||||||
debugPrintf("Startup: %u\n", (unsigned int) scene->_startup);
|
debugPrintf("Startup: %u\n", (unsigned int) scene->_startup);
|
||||||
debugPrintf("Delay: %u\n", (unsigned int) scene->_DL);
|
debugPrintf("Delay: %u\n", (unsigned int) scene->_delay);
|
||||||
debugPrintf("Doors: %u\n", (unsigned int) scene->_noDoors);
|
debugPrintf("Doors: %u\n", (unsigned int) scene->_noDoors);
|
||||||
debugPrintf("Objects: %u\n", (unsigned int) scene->_noObjects);
|
debugPrintf("Objects: %u\n", (unsigned int) scene->_noObjects);
|
||||||
debugPrintf("Statics: %u\n", (unsigned int) scene->_noStatics);
|
debugPrintf("Statics: %u\n", (unsigned int) scene->_noStatics);
|
||||||
debugPrintf("ObstacleY1: %u\n", (unsigned int) scene->_obstacleY1);
|
debugPrintf("ObstacleY1: %u\n", (unsigned int) scene->_obstacleY1);
|
||||||
debugPrintf("PalRotStart: %u\n", (unsigned int) scene->_palRotStart);
|
debugPrintf("PalRotFirst: %u\n", (unsigned int) scene->_palRotFirst);
|
||||||
debugPrintf("PalRotEnd: %u\n", (unsigned int) scene->_palRotEnd);
|
debugPrintf("PalRotLast: %u\n", (unsigned int) scene->_palRotLast);
|
||||||
debugPrintf("PalRotPeriod: %u\n", (unsigned int) scene->_palRotPeriod);
|
debugPrintf("PalRotDelay: %u\n", (unsigned int) scene->_palRotDelay);
|
||||||
} else {
|
} else {
|
||||||
debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
|
debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
|
||||||
}
|
}
|
||||||
@@ -377,19 +377,19 @@ bool Console::cmd_dumpobjectinfo(int argc, const char **argv) {
|
|||||||
if (scene) {
|
if (scene) {
|
||||||
Object *const object = scene->getObject(objectId);
|
Object *const object = scene->getObject(objectId);
|
||||||
if (object) {
|
if (object) {
|
||||||
debugPrintf("AC: %u\n", (unsigned int) object->_AC);
|
debugPrintf("AC: %u\n", (unsigned int) object->_active);
|
||||||
debugPrintf("FA: %u\n", (unsigned int) object->_FA);
|
debugPrintf("FA: %u\n", (unsigned int) object->_firstFrame);
|
||||||
debugPrintf("FR: %u\n", (unsigned int) object->_FR);
|
debugPrintf("FR: %u\n", (unsigned int) object->_randomFrame);
|
||||||
debugPrintf("NA: %u\n", (unsigned int) object->_NA);
|
debugPrintf("NA: %u\n", (unsigned int) object->_numFrames);
|
||||||
debugPrintf("FS: %u\n", (unsigned int) object->_FS);
|
debugPrintf("FS: %u\n", (unsigned int) object->_roomFrameLSB);
|
||||||
debugPrintf("Unknown: %u\n", (unsigned int) object->_unknown);
|
debugPrintf("Jump chance: %u\n", (unsigned int) object->_jumpChance);
|
||||||
debugPrintf("CA: %u\n", (unsigned int) object->_CA);
|
debugPrintf("CA: %u\n", (unsigned int) object->_currentFrame);
|
||||||
debugPrintf("X: %u\n", (unsigned int) object->_x);
|
debugPrintf("X: %u\n", (unsigned int) object->_x);
|
||||||
debugPrintf("Y: %u\n", (unsigned int) object->_y);
|
debugPrintf("Y: %u\n", (unsigned int) object->_y);
|
||||||
debugPrintf("XL: %u\n", (unsigned int) object->_XL);
|
debugPrintf("XL: %u\n", (unsigned int) object->_width);
|
||||||
debugPrintf("YL: %u\n", (unsigned int) object->_YL);
|
debugPrintf("YL: %u\n", (unsigned int) object->_height);
|
||||||
debugPrintf("WX: %u\n", (unsigned int) object->_WX);
|
debugPrintf("WX: %u\n", (unsigned int) object->_WX);
|
||||||
debugPrintf("WY: %u\n", (unsigned int) object->_WY);
|
debugPrintf("WY: %u\n", (unsigned int) object->_roomFrameMSB);
|
||||||
debugPrintf("SP: %u\n", (unsigned int) object->_SP);
|
debugPrintf("SP: %u\n", (unsigned int) object->_SP);
|
||||||
} else {
|
} else {
|
||||||
debugPrintf(_("Object %u not found.\n"), (unsigned int) objectId);
|
debugPrintf(_("Object %u not found.\n"), (unsigned int) objectId);
|
||||||
@@ -421,7 +421,7 @@ bool Console::cmd_dumpstaticinfo(int argc, const char **argv) {
|
|||||||
debugPrintf("Height: %u\n", (unsigned int) stat->_height);
|
debugPrintf("Height: %u\n", (unsigned int) stat->_height);
|
||||||
debugPrintf("WalkToX: %u\n", (unsigned int) stat->_walkToY);
|
debugPrintf("WalkToX: %u\n", (unsigned int) stat->_walkToY);
|
||||||
debugPrintf("WalkToY: %u\n", (unsigned int) stat->_walkToX);
|
debugPrintf("WalkToY: %u\n", (unsigned int) stat->_walkToX);
|
||||||
debugPrintf("WalkToFrame: %u\n", (unsigned int) stat->_SP);
|
debugPrintf("WalkToFrame: %u\n", (unsigned int) stat->_walkToFrame);
|
||||||
} else {
|
} else {
|
||||||
debugPrintf(_("Static %u not found.\n"), (unsigned int) staticId);
|
debugPrintf(_("Static %u not found.\n"), (unsigned int) staticId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,19 +58,19 @@ bool Door::loadFromStream(Common::ReadStream &stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Object::loadFromStream(Common::ReadStream &stream) {
|
bool Object::loadFromStream(Common::ReadStream &stream) {
|
||||||
_AC = stream.readByte();
|
_active = stream.readByte();
|
||||||
_FA = stream.readByte();
|
_firstFrame = stream.readByte();
|
||||||
_FR = stream.readByte();
|
_randomFrame = stream.readByte();
|
||||||
_NA = stream.readByte();
|
_numFrames = stream.readByte();
|
||||||
_FS = stream.readByte();
|
_roomFrameLSB = stream.readByte();
|
||||||
_unknown = stream.readByte();
|
_jumpChance = stream.readByte();
|
||||||
_CA = stream.readByte();
|
_currentFrame = stream.readByte();
|
||||||
_x = stream.readUint16LE();
|
_x = stream.readUint16LE();
|
||||||
_y = stream.readByte();
|
_y = stream.readByte();
|
||||||
_XL = stream.readUint16LE();
|
_width = stream.readUint16LE();
|
||||||
_YL = stream.readByte();
|
_height = stream.readByte();
|
||||||
_WX = stream.readUint16LE();
|
_WX = stream.readUint16LE();
|
||||||
_WY = stream.readByte();
|
_roomFrameMSB = stream.readByte();
|
||||||
_SP = stream.readByte();
|
_SP = stream.readByte();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -85,13 +85,13 @@ bool Static::loadFromStream(Common::ReadStream &stream) {
|
|||||||
_height = stream.readByte();
|
_height = stream.readByte();
|
||||||
_walkToX = stream.readUint16LE();
|
_walkToX = stream.readUint16LE();
|
||||||
_walkToY = stream.readByte();
|
_walkToY = stream.readByte();
|
||||||
_SP = stream.readByte();
|
_walkToFrame = stream.readByte();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bitmap::loadFromStream(Common::ReadStream &stream) {
|
bool Bitmap::loadFromStream(Common::ReadStream &stream) {
|
||||||
_frame = stream.readByte();
|
_roomFrame = stream.readByte();
|
||||||
_isVisible = stream.readByte();
|
_isVisible = stream.readByte();
|
||||||
_x1 = stream.readUint16LE();
|
_x1 = stream.readUint16LE();
|
||||||
_y1 = stream.readByte();
|
_y1 = stream.readByte();
|
||||||
@@ -108,7 +108,7 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
|
|||||||
_unknown001 = stream.readByte();
|
_unknown001 = stream.readByte();
|
||||||
_unknown002 = stream.readByte();
|
_unknown002 = stream.readByte();
|
||||||
_unknown003 = stream.readByte();
|
_unknown003 = stream.readByte();
|
||||||
_DL = stream.readByte();
|
_delay = stream.readByte();
|
||||||
|
|
||||||
_noDoors = stream.readByte();
|
_noDoors = stream.readByte();
|
||||||
_noDoors = MIN(_noDoors, (uint8) ARRAYSIZE(_doors));
|
_noDoors = MIN(_noDoors, (uint8) ARRAYSIZE(_doors));
|
||||||
@@ -133,9 +133,9 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_obstacleY1 = stream.readUint16LE();
|
_obstacleY1 = stream.readUint16LE();
|
||||||
_palRotStart = stream.readByte();
|
_palRotFirst = stream.readByte();
|
||||||
_palRotEnd = stream.readByte();
|
_palRotLast = stream.readByte();
|
||||||
_palRotPeriod = stream.readByte();
|
_palRotDelay = stream.readByte();
|
||||||
_exhaustedChoiceNext = stream.readByte();
|
_exhaustedChoiceNext = stream.readByte();
|
||||||
|
|
||||||
for (i = 0; i < 79; ++i) {
|
for (i = 0; i < 79; ++i) {
|
||||||
|
|||||||
+177
-64
@@ -36,40 +36,49 @@ enum {
|
|||||||
MAX_ENTITY_NAME_LENGTH = 0x14
|
MAX_ENTITY_NAME_LENGTH = 0x14
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/** @file gamedata.h
|
||||||
There are 4 types of entities present in the game data:
|
* There are 4 types of entities present in the game data:
|
||||||
- Door
|
* - Door
|
||||||
- Object
|
* - Object
|
||||||
- Static
|
* - Static
|
||||||
- Bitmap
|
* - Bitmap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interactable scene changer with no visual representation.
|
||||||
|
*/
|
||||||
struct Door {
|
struct Door {
|
||||||
/*
|
/**
|
||||||
Door name.
|
* Door name (NM register).
|
||||||
Can be empty - deactivates door completely.
|
*
|
||||||
*/
|
* Can be empty - deactivates door completely (you can't mouse over or interact with it at all).
|
||||||
|
*
|
||||||
|
* If it ends with '+', using the "go" verb on the door will not implicitly change the scene,
|
||||||
|
* but the player will still walk towards the door.
|
||||||
|
*
|
||||||
|
* TODO: Implement the '+' restriction.
|
||||||
|
*/
|
||||||
char _name[MAX_ENTITY_NAME_LENGTH + 1];
|
char _name[MAX_ENTITY_NAME_LENGTH + 1];
|
||||||
/*
|
/**
|
||||||
Scene ID where the door leads.
|
* Scene ID where the door leads (LT register).
|
||||||
Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
|
* Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
|
||||||
*/
|
*/
|
||||||
uint8 _destSceneId;
|
uint8 _destSceneId;
|
||||||
/* X coordinate for player's position after going through the door. */
|
/** X coordinate for player's position after going through the door (SX register). */
|
||||||
uint16 _destX;
|
uint16 _destX;
|
||||||
/* Y coordinate for player's position after going through the door. */
|
/** Y coordinate for player's position after going through the door (SY register). */
|
||||||
uint16 _destY;
|
uint16 _destY;
|
||||||
/* X coordinate of the door rectangle. */
|
/** X coordinate of the door rectangle (XX register). */
|
||||||
uint16 _x;
|
uint16 _x;
|
||||||
/* Y coordinate of the door rectangle. */
|
/** Y coordinate of the door rectangle (YY register). */
|
||||||
uint8 _y;
|
uint8 _y;
|
||||||
/* Width of the door rectangle. */
|
/** Width of the door rectangle (XL register). */
|
||||||
uint16 _width;
|
uint16 _width;
|
||||||
/* Height of the door rectangle. */
|
/** Height of the door rectangle (YL register). */
|
||||||
uint8 _height;
|
uint8 _height;
|
||||||
/* X coordinate for position towards player will walk after clicking the door. */
|
/** X coordinate for position player will walk towards after clicking the door (WX register). */
|
||||||
uint16 _walkToX;
|
uint16 _walkToX;
|
||||||
/* Y coordinate for position towards player will walk after clicking the door. */
|
/** Y coordinate for position player will walk towards after clicking the door (WY register). */
|
||||||
uint8 _walkToY;
|
uint8 _walkToY;
|
||||||
/* Unknown for now - likely not even used. */
|
/* Unknown for now - likely not even used. */
|
||||||
uint8 _SP;
|
uint8 _SP;
|
||||||
@@ -77,56 +86,148 @@ struct Door {
|
|||||||
bool loadFromStream(Common::ReadStream &stream);
|
bool loadFromStream(Common::ReadStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An animated image in the scene.
|
||||||
|
*
|
||||||
|
* Object frames consist of surfaces carved out of room frames (starting from _roomFrame
|
||||||
|
* up until _roomFrame + _numFrames - 1) based on the object's rectangle. They are stored
|
||||||
|
* in the shared object frame space that each object occupies a continous part of from
|
||||||
|
* the beginning.
|
||||||
|
*
|
||||||
|
* By using the term "frame" alone we will be referring to an object frame, not a room
|
||||||
|
* frame.
|
||||||
|
*
|
||||||
|
* For details regarding animation playback, see objectanimationtask.cpp.
|
||||||
|
*/
|
||||||
struct Object {
|
struct Object {
|
||||||
uint8 _AC;
|
/** Controls whether the animation is playing. */
|
||||||
uint8 _FA;
|
|
||||||
uint8 _FR;
|
|
||||||
uint8 _NA;
|
|
||||||
uint8 _FS;
|
|
||||||
uint8 _unknown;
|
|
||||||
uint8 _CA;
|
|
||||||
uint16 _x;
|
|
||||||
uint8 _y;
|
|
||||||
uint16 _XL;
|
|
||||||
uint8 _YL;
|
|
||||||
uint16 _WX;
|
|
||||||
uint8 _WY;
|
|
||||||
uint8 _SP;
|
|
||||||
|
|
||||||
bool loadFromStream(Common::ReadStream &stream);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Static {
|
|
||||||
uint8 _active;
|
uint8 _active;
|
||||||
char _name[MAX_ENTITY_NAME_LENGTH + 1];
|
/**
|
||||||
|
* Number of the first frame this object has in the shared object frame space (FA register).
|
||||||
|
*
|
||||||
|
* For the first object, it is equal to 1.
|
||||||
|
* For any subsequent object, it is equal to (_firstFrame + _numFrames) of the previous object.
|
||||||
|
*
|
||||||
|
* @note The numbering starts from 1.
|
||||||
|
* @note Technically this field is useless because it can be calculated.
|
||||||
|
*/
|
||||||
|
uint8 _firstFrame;
|
||||||
|
/**
|
||||||
|
* The frame that is jumped to randomly based on _jumpChance (FR register).
|
||||||
|
*
|
||||||
|
* @note Numbered from 1 and relative to _firstFrame.
|
||||||
|
* @note A value of 0 disables randomness completely.
|
||||||
|
* @see objectanimationtask.cpp
|
||||||
|
* @see _jumpChance
|
||||||
|
*/
|
||||||
|
uint8 _randomFrame;
|
||||||
|
/** Number of animation frames (NA register). */
|
||||||
|
uint8 _numFrames;
|
||||||
|
/**
|
||||||
|
* Low 8 bits of the 16-bit starting room frame (FS register).
|
||||||
|
*
|
||||||
|
* @see _roomFrameMSB
|
||||||
|
*/
|
||||||
|
uint8 _roomFrameLSB;
|
||||||
|
/**
|
||||||
|
* Chance (1 in x) of the animation jumping to _randomFrame.
|
||||||
|
*
|
||||||
|
* @see objectanimationtask.cpp
|
||||||
|
*/
|
||||||
|
uint8 _jumpChance;
|
||||||
|
/**
|
||||||
|
* Current animation frame (CA register).
|
||||||
|
*
|
||||||
|
* @note Absolute index to the frame space. Numbered from 1.
|
||||||
|
*/
|
||||||
|
uint8 _currentFrame;
|
||||||
|
/** X coordinate of the object rectangle (XX register). */
|
||||||
uint16 _x;
|
uint16 _x;
|
||||||
|
/** Y coordinate of the object rectangle (YY register). */
|
||||||
uint8 _y;
|
uint8 _y;
|
||||||
|
/** Width of the object rectangle (XL register). */
|
||||||
uint16 _width;
|
uint16 _width;
|
||||||
|
/** Height of the object rectangle (YL register). */
|
||||||
uint8 _height;
|
uint8 _height;
|
||||||
uint16 _walkToX;
|
/** A general-purpose register for use in scripts. Nothing to do with animation. */
|
||||||
uint8 _walkToY;
|
uint16 _WX;
|
||||||
|
/**
|
||||||
|
* High 8 bits of the 16-bit starting room frame (WY register).
|
||||||
|
*
|
||||||
|
* @see _roomFrameLSB
|
||||||
|
*/
|
||||||
|
uint8 _roomFrameMSB;
|
||||||
|
/* Unknown. TODO: Figure out what this does. */
|
||||||
uint8 _SP;
|
uint8 _SP;
|
||||||
|
|
||||||
bool loadFromStream(Common::ReadStream &stream);
|
bool loadFromStream(Common::ReadStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interactable area without a visual representation.
|
||||||
|
*/
|
||||||
|
struct Static {
|
||||||
|
/** Whether you can mouse over and interact with the static (AC register). */
|
||||||
|
uint8 _active;
|
||||||
|
/**
|
||||||
|
* Static name (NM register).
|
||||||
|
*
|
||||||
|
* If it starts with '~', the static has an implicit "pickup" action that adds
|
||||||
|
* an item with the same name (except '`' replaces '~') to your inventory and
|
||||||
|
* disables the static. If there is a matching scripted "pickup" action, it
|
||||||
|
* overrides the implicit action.
|
||||||
|
*
|
||||||
|
* TODO: Support '~' statics.
|
||||||
|
*/
|
||||||
|
char _name[MAX_ENTITY_NAME_LENGTH + 1];
|
||||||
|
/** X coordinate of the static rectangle (XX register). */
|
||||||
|
uint16 _x;
|
||||||
|
/** Y coordinate of the static rectangle (YY register). */
|
||||||
|
uint8 _y;
|
||||||
|
/** Width of the static rectangle (XL register). */
|
||||||
|
uint16 _width;
|
||||||
|
/** Height of the static rectangle (YL register). */
|
||||||
|
uint8 _height;
|
||||||
|
/** X coordinate of the position the player will walk towards after clicking the static (WX register). */
|
||||||
|
uint16 _walkToX;
|
||||||
|
/** Y coordinate of the position the player will walk towards after clicking the static (WY register). */
|
||||||
|
uint8 _walkToY;
|
||||||
|
/** Player frame (rotation) set after the player finishes walking towards the walk to position (SP register). */
|
||||||
|
uint8 _walkToFrame;
|
||||||
|
|
||||||
|
bool loadFromStream(Common::ReadStream &stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A static image that is carved out of a room frame based on its rectangle.
|
||||||
|
* The bitmap rectangle also specifies where to blit it on the screen.
|
||||||
|
*/
|
||||||
struct Bitmap {
|
struct Bitmap {
|
||||||
uint8 _frame;
|
/** Room frame that this bitmap carves out of. */
|
||||||
|
uint8 _roomFrame;
|
||||||
|
/** Whether to draw the bitmap. */
|
||||||
uint8 _isVisible;
|
uint8 _isVisible;
|
||||||
|
/** X coordinate of the top left corner of the bitmap rectangle. */
|
||||||
uint16 _x1;
|
uint16 _x1;
|
||||||
|
/** Y coordinate of the top left corner of the bitmap rectangle. */
|
||||||
uint8 _y1;
|
uint8 _y1;
|
||||||
|
/** X coordinate of the bottom right corner of the bitmap rectangle. */
|
||||||
uint16 _x2;
|
uint16 _x2;
|
||||||
|
/** Y coordinate of the bottom right corner of the bitmap rectangle. */
|
||||||
uint8 _y2;
|
uint8 _y2;
|
||||||
|
|
||||||
bool loadFromStream(Common::ReadStream &stream);
|
bool loadFromStream(Common::ReadStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoded exhausted choice.
|
||||||
|
*/
|
||||||
struct ExhaustedChoice {
|
struct ExhaustedChoice {
|
||||||
/*
|
/**
|
||||||
1 bit - context
|
* 1 bit - context
|
||||||
3 bits - choice index
|
* 3 bits - choice index
|
||||||
4 bits - choice list index
|
* 4 bits - choice list index
|
||||||
*/
|
*/
|
||||||
uint8 _encodedData;
|
uint8 _encodedData;
|
||||||
|
|
||||||
uint8 getContext() const { return (_encodedData >> 7) & 0x1; }
|
uint8 getContext() const { return (_encodedData >> 7) & 0x1; }
|
||||||
@@ -154,29 +255,41 @@ struct Scene {
|
|||||||
void addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList);
|
void addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList);
|
||||||
bool isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) const;
|
bool isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) const;
|
||||||
|
|
||||||
|
/** Refers to the script block that will be executed when you enter this scene (DS register). */
|
||||||
uint8 _startup;
|
uint8 _startup;
|
||||||
|
/**
|
||||||
|
* These three variables control downscaling of the player character depending on his Y.
|
||||||
|
* TODO: Find out more.
|
||||||
|
*/
|
||||||
uint8 _unknown001;
|
uint8 _unknown001;
|
||||||
uint8 _unknown002;
|
uint8 _unknown002;
|
||||||
uint8 _unknown003;
|
uint8 _unknown003;
|
||||||
uint8 _DL;
|
uint8 _delay; /**< Delay between object animation advancements (DL register). */
|
||||||
|
|
||||||
uint8 _noDoors;
|
uint8 _noDoors; /**< Number of doors in the scene (ND register). */
|
||||||
Door _doors[5];
|
Door _doors[5]; /**< Door definitions. */
|
||||||
|
|
||||||
uint8 _noObjects;
|
uint8 _noObjects; /**< Number of animated objects in the scene (NO register). */
|
||||||
Object _objects[9];
|
Object _objects[9]; /**< Object definitions. */
|
||||||
|
|
||||||
uint8 _noStatics;
|
uint8 _noStatics; /**< Number of statics in the scene (NS register). */
|
||||||
Static _statics[15];
|
Static _statics[15]; /**< Static definitions. */
|
||||||
|
|
||||||
Bitmap _bitmaps[10];
|
Bitmap _bitmaps[10]; /**< Bitmap definitions. There is no corresponding _noBitmaps field. */
|
||||||
|
|
||||||
uint16 _obstacleY1;
|
uint16 _obstacleY1; /**< Fixed Y coordinate for all static obstacles in the scene. Always 0 in data files. */
|
||||||
uint8 _palRotStart;
|
|
||||||
uint8 _palRotEnd;
|
|
||||||
uint8 _palRotPeriod;
|
|
||||||
|
|
||||||
/* Points to the first free item in exhausted choices list. */
|
/** First index (inclusive and 0-indexed) of the rotating portion of the palette (PF register). */
|
||||||
|
uint8 _palRotFirst;
|
||||||
|
/** Last index (inclusive and 0-indexed) of the rotating portion of the palette (PL register). */
|
||||||
|
uint8 _palRotLast;
|
||||||
|
/** Delay between each right rotation of the palette portion (PD register). */
|
||||||
|
uint8 _palRotDelay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to the first free item in exhausted choices list.
|
||||||
|
* @note Indexed from 1.
|
||||||
|
*/
|
||||||
uint8 _exhaustedChoiceNext;
|
uint8 _exhaustedChoiceNext;
|
||||||
ExhaustedChoice _exhaustedChoices[79];
|
ExhaustedChoice _exhaustedChoices[79];
|
||||||
|
|
||||||
|
|||||||
@@ -71,12 +71,12 @@ void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surfa
|
|||||||
const uint8 noObjects = scene->getNoObjects();
|
const uint8 noObjects = scene->getNoObjects();
|
||||||
for (int i = 0; i < noObjects; ++i) {
|
for (int i = 0; i < noObjects; ++i) {
|
||||||
Object &object = scene->_objects[i];
|
Object &object = scene->_objects[i];
|
||||||
const uint16 startFrame = (object._WY << 8) + object._FS;
|
const uint16 startFrame = (object._roomFrameMSB << 8) + object._roomFrameLSB;
|
||||||
if (frameNo1 >= startFrame && frameNo1 < startFrame + object._NA) {
|
if (frameNo1 >= startFrame && frameNo1 < startFrame + object._numFrames) {
|
||||||
const int x = object._x;
|
const int x = object._x;
|
||||||
const int y = object._y;
|
const int y = object._y;
|
||||||
const int w = (object._XL + 3) / 4 * 4; // Original code uses this to round up width to a multiple of 4.
|
const int w = (object._width + 3) / 4 * 4; // Original code uses this to round up width to a multiple of 4.
|
||||||
const int h = object._YL;
|
const int h = object._height;
|
||||||
Common::Rect rect(x, y, x + w, y + h);
|
Common::Rect rect(x, y, x + w, y + h);
|
||||||
|
|
||||||
const Graphics::Surface sharedSurface = surface.getSubArea(rect);
|
const Graphics::Surface sharedSurface = surface.getSubArea(rect);
|
||||||
@@ -100,11 +100,11 @@ bool Room::load(uint8 roomNumber, bool roomB) {
|
|||||||
for (int i = 0; i < noObjects; ++i) {
|
for (int i = 0; i < noObjects; ++i) {
|
||||||
uint8 firstIndex = 0;
|
uint8 firstIndex = 0;
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
firstIndex = _objectsStart[i - 1] + scene->_objects[i - 1]._NA;
|
firstIndex = _objectsStart[i - 1] + scene->_objects[i - 1]._numFrames;
|
||||||
}
|
}
|
||||||
_objectsStart.push_back(firstIndex);
|
_objectsStart.push_back(firstIndex);
|
||||||
|
|
||||||
uint8 numAnims = scene->_objects[i]._NA;
|
uint8 numAnims = scene->_objects[i]._numFrames;
|
||||||
while (numAnims--) {
|
while (numAnims--) {
|
||||||
_surfaces.push_back(Graphics::Surface());
|
_surfaces.push_back(Graphics::Surface());
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ void Room::redraw() {
|
|||||||
Scene *const currentScene = _game->getGameData().getCurrentScene();
|
Scene *const currentScene = _game->getGameData().getCurrentScene();
|
||||||
for (int i = 0; i < currentScene->getNoObjects(); ++i) {
|
for (int i = 0; i < currentScene->getNoObjects(); ++i) {
|
||||||
Object *const obj = currentScene->getObject(i + 1);
|
Object *const obj = currentScene->getObject(i + 1);
|
||||||
if (obj->_AC) {
|
if (obj->_active) {
|
||||||
drawObjectAnimation(i + 1, 0);
|
drawObjectAnimation(i + 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace MutationOfJB {
|
|||||||
|
|
||||||
static const int TICK_MILLIS = 100;
|
static const int TICK_MILLIS = 100;
|
||||||
|
|
||||||
|
// TODO: Respect currentScene._delay.
|
||||||
ObjectAnimationTask::ObjectAnimationTask() : _timer(TICK_MILLIS) {
|
ObjectAnimationTask::ObjectAnimationTask() : _timer(TICK_MILLIS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +48,17 @@ void ObjectAnimationTask::update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advances every object animation in the current scene to the next frame.
|
||||||
|
*
|
||||||
|
* Normally the animation restarts after the last object frame. However, some animations have random
|
||||||
|
* elements to them. If _randomFrame is set, the animation restarts when _randomFrame is reached.
|
||||||
|
* Additionally, there is a chance with each frame until _randomFrame that the animation may jump
|
||||||
|
* straight to _randomFrame and continue until the last frame, then wrap around to the first frame.
|
||||||
|
*
|
||||||
|
* Randomness is used to introduce variety - e.g. in the starting scene a perched bird occassionally
|
||||||
|
* spreads its wings.
|
||||||
|
*/
|
||||||
void ObjectAnimationTask::updateObjects() {
|
void ObjectAnimationTask::updateObjects() {
|
||||||
Scene *const scene = getTaskManager()->getGame().getGameData().getCurrentScene();
|
Scene *const scene = getTaskManager()->getGame().getGameData().getCurrentScene();
|
||||||
if (!scene) {
|
if (!scene) {
|
||||||
@@ -56,34 +68,34 @@ void ObjectAnimationTask::updateObjects() {
|
|||||||
for (uint8 i = 1; i <= scene->getNoObjects(); ++i) {
|
for (uint8 i = 1; i <= scene->getNoObjects(); ++i) {
|
||||||
Object *const object = scene->getObject(i);
|
Object *const object = scene->getObject(i);
|
||||||
// Skip if object animation not active.
|
// Skip if object animation not active.
|
||||||
if (!object->_AC)
|
if (!object->_active)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Number of framers must be higher than 1.
|
// Number of frames must be higher than 1.
|
||||||
if (object->_NA <= 1)
|
if (object->_numFrames <= 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const uint8 currentAnimOffset = object->_CA - object->_FA;
|
const uint8 currentAnimOffset = object->_currentFrame - object->_firstFrame;
|
||||||
|
|
||||||
const bool randomized = object->_FR != 0;
|
const bool randomized = object->_randomFrame != 0;
|
||||||
const bool belowRandomFrame = currentAnimOffset < (object->_FR - 1);
|
const bool belowRandomFrame = currentAnimOffset < (object->_randomFrame - 1);
|
||||||
|
|
||||||
uint8 maxAnimOffset = object->_NA - 1;
|
uint8 maxAnimOffset = object->_numFrames - 1;
|
||||||
if (randomized && belowRandomFrame) {
|
if (randomized && belowRandomFrame) {
|
||||||
maxAnimOffset = object->_FR - 2;
|
maxAnimOffset = object->_randomFrame - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 nextAnimationOffset = currentAnimOffset + 1;
|
uint8 nextAnimationOffset = currentAnimOffset + 1;
|
||||||
if (currentAnimOffset == maxAnimOffset) {
|
if (currentAnimOffset == maxAnimOffset) {
|
||||||
if (randomized && object->_unknown != 0 && getTaskManager()->getGame().getRandomSource().getRandomNumber(object->_unknown) == 0)
|
if (randomized && object->_jumpChance != 0 && getTaskManager()->getGame().getRandomSource().getRandomNumber(object->_jumpChance) == 0)
|
||||||
nextAnimationOffset = object->_FR - 1;
|
nextAnimationOffset = object->_randomFrame - 1;
|
||||||
else
|
else
|
||||||
nextAnimationOffset = 0;
|
nextAnimationOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Hardcoded animations.
|
// TODO: Hardcoded animations.
|
||||||
|
|
||||||
object->_CA = nextAnimationOffset + object->_FA;
|
object->_currentFrame = nextAnimationOffset + object->_firstFrame;
|
||||||
getTaskManager()->getGame().getRoom().drawObjectAnimation(i, nextAnimationOffset);
|
getTaskManager()->getGame().getRoom().drawObjectAnimation(i, nextAnimationOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,10 +60,12 @@ void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY,
|
|||||||
Common::Array<Common::String> lines;
|
Common::Array<Common::String> lines;
|
||||||
font.wordWrap(text, MAX_LINE_WIDTH, lines);
|
font.wordWrap(text, MAX_LINE_WIDTH, lines);
|
||||||
|
|
||||||
|
// Get the x, y coordinates of the top center point of the text's bounding box
|
||||||
|
// from the (rather strange) talk coordinates coming from scripts.
|
||||||
int16 x = talkX;
|
int16 x = talkX;
|
||||||
int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15; // Get the top y
|
int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15;
|
||||||
|
|
||||||
// Clamp to screen edges
|
// Clamp to screen edges.
|
||||||
y = MAX<int16>(y, 3);
|
y = MAX<int16>(y, 3);
|
||||||
int16 maxWidth = 0;
|
int16 maxWidth = 0;
|
||||||
for (uint i = 0; i < lines.size(); i++) {
|
for (uint i = 0; i < lines.size(); i++) {
|
||||||
@@ -75,12 +77,12 @@ void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY,
|
|||||||
x = MIN<int16>(x, 317 - lineWidth / 2);
|
x = MIN<int16>(x, 317 - lineWidth / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw lines
|
// Draw lines.
|
||||||
for (uint i = 0; i < lines.size(); i++) {
|
for (uint i = 0; i < lines.size(); i++) {
|
||||||
font.drawString(lines[i], color, x - font.getWidth(lines[i]) / 2, y + i * font.getLineHeight(), getTaskManager()->getGame().getScreen());
|
font.drawString(lines[i], color, x - font.getWidth(lines[i]) / 2, y + i * font.getLineHeight(), getTaskManager()->getGame().getScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember the area occupied by the text
|
// Remember the area occupied by the text.
|
||||||
_boundingBox.top = x - maxWidth / 2;
|
_boundingBox.top = x - maxWidth / 2;
|
||||||
_boundingBox.left = y;
|
_boundingBox.left = y;
|
||||||
_boundingBox.setWidth(maxWidth);
|
_boundingBox.setWidth(maxWidth);
|
||||||
|
|||||||
Reference in New Issue
Block a user