mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 13:50:13 +00:00
FREESCAPE: implemented timed condition executions from dark (and other games)
This commit is contained in:
parent
b13065da36
commit
77728fcf73
@ -526,7 +526,7 @@ bool FreescapeEngine::onScreenControls(Common::Point mouse) {
|
||||
|
||||
void FreescapeEngine::executeMovementConditions() {
|
||||
// Only execute "on collision" room/global conditions
|
||||
executeLocalGlobalConditions(false, true);
|
||||
executeLocalGlobalConditions(false, true, false);
|
||||
}
|
||||
|
||||
void FreescapeEngine::updateTimeVariables() {
|
||||
@ -537,7 +537,7 @@ void FreescapeEngine::updateTimeVariables() {
|
||||
_lastMinute = minutes;
|
||||
_gameStateVars[0x1e] += 1;
|
||||
_gameStateVars[0x1f] += 1;
|
||||
executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
|
||||
executeLocalGlobalConditions(false, true, false); // Only execute "on collision" room/global conditions
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,8 +276,8 @@ public:
|
||||
Math::Vector3d _objExecutingCodeSize;
|
||||
virtual void executeMovementConditions();
|
||||
void executeObjectConditions(GeometricObject *obj, bool shot, bool collided);
|
||||
void executeLocalGlobalConditions(bool shot, bool collided);
|
||||
void executeCode(FCLInstructionVector &code, bool shot, bool collided);
|
||||
void executeLocalGlobalConditions(bool shot, bool collided, bool timer);
|
||||
void executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer);
|
||||
|
||||
// Instructions
|
||||
void executeIncrementVariable(FCLInstruction &instruction);
|
||||
@ -531,7 +531,6 @@ public:
|
||||
|
||||
int _lastTenSeconds;
|
||||
void updateTimeVariables() override;
|
||||
void executeMovementConditions() override;
|
||||
|
||||
void drawDOSUI(Graphics::Surface *surface) override;
|
||||
void drawFullscreenMessage(Common::String message);
|
||||
|
@ -201,27 +201,20 @@ void DarkEngine::checkIfStillInArea() {
|
||||
FreescapeEngine::checkIfStillInArea();
|
||||
}
|
||||
|
||||
void DarkEngine::executeMovementConditions() {
|
||||
// Only execute "on collision" room/global conditions
|
||||
if (_currentArea->getAreaFlags() == 1)
|
||||
executeLocalGlobalConditions(false, true);
|
||||
}
|
||||
|
||||
void DarkEngine::updateTimeVariables() {
|
||||
// This function only executes "on collision" room/global conditions
|
||||
int seconds, minutes, hours;
|
||||
getTimeFromCountdown(seconds, minutes, hours);
|
||||
if (_lastTenSeconds != seconds / 10) {
|
||||
_lastTenSeconds = seconds / 10;
|
||||
if (_currentArea->getAreaFlags() == 0)
|
||||
executeLocalGlobalConditions(false, true);
|
||||
executeLocalGlobalConditions(false, false, true);
|
||||
}
|
||||
|
||||
if (_lastMinute != minutes) {
|
||||
_lastMinute = minutes;
|
||||
_gameStateVars[0x1e] += 1;
|
||||
_gameStateVars[0x1f] += 1;
|
||||
executeLocalGlobalConditions(false, true);
|
||||
executeLocalGlobalConditions(false, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,9 +39,8 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
|
||||
Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
|
||||
|
||||
// on the 8bit platforms, all instructions have a conditional flag;
|
||||
// we'll want to convert them into runs of "if shot? then" and "if collided? then",
|
||||
// we'll want to convert them into runs of "if shot? then", "if collided? then" or "if timer? then",
|
||||
// and we'll want to start that from the top
|
||||
uint8 conditionalIsShot = 0x1;
|
||||
FCLInstructionVector *conditionalInstructions = new FCLInstructionVector();
|
||||
FCLInstruction currentInstruction;
|
||||
|
||||
@ -55,30 +54,42 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
|
||||
0, 0, 0, 0, 0, 0, 2, 2,
|
||||
1};
|
||||
|
||||
detokenisedStream += Common::String::format("CONDITION FLAG: %x\n", tokenisedCondition[0]);
|
||||
Token::Type newConditional;
|
||||
Token::Type oldConditional;
|
||||
|
||||
while (bytePointer < sizeOfTokenisedContent) {
|
||||
// get the conditional type of the next operation
|
||||
uint8 newConditionalIsShot = tokenisedCondition[bytePointer] & 0x80;
|
||||
uint8 conditionalByte = tokenisedCondition[bytePointer];
|
||||
|
||||
if (conditionalByte & 0x80)
|
||||
newConditional = Token::SHOTQ;
|
||||
else if (conditionalByte & 0x40)
|
||||
newConditional = Token::TIMERQ;
|
||||
else
|
||||
newConditional = Token::COLLIDEDQ;
|
||||
|
||||
// if the conditional type has changed then end the old conditional,
|
||||
// if we were in one, and begin a new one
|
||||
if (newConditionalIsShot != conditionalIsShot) {
|
||||
if (bytePointer == 0 || newConditional != oldConditional) {
|
||||
oldConditional = newConditional;
|
||||
FCLInstruction branch;
|
||||
if (conditionalIsShot)
|
||||
branch = FCLInstruction(Token::SHOTQ);
|
||||
else
|
||||
branch = FCLInstruction(Token::COLLIDEDQ);
|
||||
branch = FCLInstruction(oldConditional);
|
||||
|
||||
branch.setBranches(conditionalInstructions, nullptr);
|
||||
instructions.push_back(branch);
|
||||
|
||||
conditionalIsShot = newConditionalIsShot;
|
||||
if (bytePointer)
|
||||
if (bytePointer > 0)
|
||||
detokenisedStream += "ENDIF\n";
|
||||
|
||||
if (conditionalIsShot)
|
||||
if (oldConditional == Token::SHOTQ)
|
||||
detokenisedStream += "IF SHOT? THEN\n";
|
||||
else
|
||||
else if (oldConditional == Token::TIMERQ)
|
||||
detokenisedStream += "IF TIMER? THEN\n";
|
||||
else if (oldConditional == Token::COLLIDEDQ)
|
||||
detokenisedStream += "IF COLLIDED? THEN\n";
|
||||
else
|
||||
error("Invalid conditional: %x", oldConditional);
|
||||
|
||||
// Allocate the next vector of instructions
|
||||
conditionalInstructions = new FCLInstructionVector();
|
||||
@ -415,10 +426,7 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
|
||||
// conditionalInstructions->push_back(currentInstruction);
|
||||
|
||||
FCLInstruction branch;
|
||||
if (conditionalIsShot)
|
||||
branch = FCLInstruction(Token::SHOTQ);
|
||||
else
|
||||
branch = FCLInstruction(Token::COLLIDEDQ);
|
||||
branch = FCLInstruction(oldConditional);
|
||||
|
||||
branch.setBranches(conditionalInstructions, nullptr);
|
||||
instructions.push_back(branch);
|
||||
|
@ -72,11 +72,11 @@ void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, b
|
||||
_firstSound = true;
|
||||
_objExecutingCodeSize = obj->getSize();
|
||||
debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->_conditionSource.c_str());
|
||||
executeCode(obj->_condition, shot, collided);
|
||||
executeCode(obj->_condition, shot, collided, false); // TODO: check this last parameter
|
||||
}
|
||||
}
|
||||
|
||||
void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided) {
|
||||
void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided, bool timer) {
|
||||
if (isCastle())
|
||||
return;
|
||||
debugC(1, kFreescapeDebugCode, "Executing room conditions");
|
||||
@ -85,17 +85,17 @@ void FreescapeEngine::executeLocalGlobalConditions(bool shot, bool collided) {
|
||||
|
||||
for (uint i = 0; i < conditions.size(); i++) {
|
||||
debugC(1, kFreescapeDebugCode, "%s", conditionSources[i].c_str());
|
||||
executeCode(conditions[i], shot, collided);
|
||||
executeCode(conditions[i], shot, collided, timer);
|
||||
}
|
||||
|
||||
debugC(1, kFreescapeDebugCode, "Executing global conditions (%d)", _conditions.size());
|
||||
for (uint i = 0; i < _conditions.size(); i++) {
|
||||
debugC(1, kFreescapeDebugCode, "%s", _conditionSources[i].c_str());
|
||||
executeCode(_conditions[i], shot, collided);
|
||||
executeCode(_conditions[i], shot, collided, timer);
|
||||
}
|
||||
}
|
||||
|
||||
void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided) {
|
||||
void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer) {
|
||||
assert(!(shot && collided));
|
||||
int ip = 0;
|
||||
int codeSize = code.size();
|
||||
@ -109,13 +109,19 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
|
||||
break;
|
||||
case Token::COLLIDEDQ:
|
||||
if (collided)
|
||||
executeCode(*instruction._thenInstructions, shot, collided);
|
||||
executeCode(*instruction._thenInstructions, shot, collided, timer);
|
||||
// else branch is always empty
|
||||
assert(instruction._elseInstructions == nullptr);
|
||||
break;
|
||||
case Token::SHOTQ:
|
||||
if (shot)
|
||||
executeCode(*instruction._thenInstructions, shot, collided);
|
||||
executeCode(*instruction._thenInstructions, shot, collided, timer);
|
||||
// else branch is always empty
|
||||
assert(instruction._elseInstructions == nullptr);
|
||||
break;
|
||||
case Token::TIMERQ:
|
||||
if (timer)
|
||||
executeCode(*instruction._thenInstructions, shot, collided, timer);
|
||||
// else branch is always empty
|
||||
assert(instruction._elseInstructions == nullptr);
|
||||
break;
|
||||
|
@ -92,7 +92,7 @@ void FreescapeEngine::shoot() {
|
||||
|
||||
executeObjectConditions(gobj, true, false);
|
||||
}
|
||||
executeLocalGlobalConditions(true, false); // Only execute "on shot" room/global conditions
|
||||
executeLocalGlobalConditions(true, false, false); // Only execute "on shot" room/global conditions
|
||||
}
|
||||
|
||||
void FreescapeEngine::changePlayerHeight(int index) {
|
||||
|
Loading…
Reference in New Issue
Block a user