mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-02 17:03:13 +00:00
FREESCAPE: refactored conditional handling to make it work with castle
This commit is contained in:
parent
fc0b1480c1
commit
c4a0d162fb
@ -281,6 +281,7 @@ public:
|
|||||||
void executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer);
|
void executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer);
|
||||||
|
|
||||||
// Instructions
|
// Instructions
|
||||||
|
bool checkConditional(FCLInstruction &instruction, bool shot, bool collided, bool timer, bool activated);
|
||||||
bool checkIfGreaterOrEqual(FCLInstruction &instruction);
|
bool checkIfGreaterOrEqual(FCLInstruction &instruction);
|
||||||
void executeIncrementVariable(FCLInstruction &instruction);
|
void executeIncrementVariable(FCLInstruction &instruction);
|
||||||
void executeDecrementVariable(FCLInstruction &instruction);
|
void executeDecrementVariable(FCLInstruction &instruction);
|
||||||
|
@ -33,7 +33,7 @@ uint8 k8bitMaxVariable = 64;
|
|||||||
uint8 k8bitMaxShield = 64;
|
uint8 k8bitMaxShield = 64;
|
||||||
uint8 k8bitMaxEnergy = 64;
|
uint8 k8bitMaxEnergy = 64;
|
||||||
|
|
||||||
Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions, bool enableActivated) {
|
Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions, bool multipleConditionals) {
|
||||||
Common::String detokenisedStream;
|
Common::String detokenisedStream;
|
||||||
Common::Array<uint8>::size_type bytePointer = 0;
|
Common::Array<uint8>::size_type bytePointer = 0;
|
||||||
Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
|
Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
|
||||||
@ -56,28 +56,30 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
|
|||||||
|
|
||||||
if (sizeOfTokenisedContent > 0)
|
if (sizeOfTokenisedContent > 0)
|
||||||
detokenisedStream += Common::String::format("CONDITION FLAG: %x\n", tokenisedCondition[0]);
|
detokenisedStream += Common::String::format("CONDITION FLAG: %x\n", tokenisedCondition[0]);
|
||||||
Token::Type newConditional = Token::UNKNOWN;
|
uint16 newConditional = 0;
|
||||||
Token::Type oldConditional = Token::UNKNOWN;
|
uint16 oldConditional = 0;
|
||||||
|
|
||||||
while (bytePointer < sizeOfTokenisedContent) {
|
while (bytePointer < sizeOfTokenisedContent) {
|
||||||
// get the conditional type of the next operation
|
// get the conditional type of the next operation
|
||||||
uint8 conditionalByte = tokenisedCondition[bytePointer];
|
uint8 conditionalByte = tokenisedCondition[bytePointer] & 0xc0;
|
||||||
|
//detokenisedStream += Common::String::format("CONDITION FLAG: %x\n", conditionalByte);
|
||||||
|
newConditional = 0;
|
||||||
|
|
||||||
if ((conditionalByte & 0xc0) && enableActivated) {
|
if (conditionalByte == 0x40)
|
||||||
newConditional = Token::ACTIVATEDQ;
|
newConditional = kConditionalTimeout;
|
||||||
} else if (conditionalByte & 0x80)
|
else if (conditionalByte == 0x80)
|
||||||
newConditional = Token::SHOTQ;
|
newConditional = kConditionalShot;
|
||||||
else if (conditionalByte & 0x40)
|
else if (conditionalByte == 0xc0)
|
||||||
newConditional = Token::TIMERQ;
|
newConditional = kConditionalActivated;
|
||||||
else
|
else
|
||||||
newConditional = Token::COLLIDEDQ;
|
newConditional = kConditionalCollided;
|
||||||
|
|
||||||
// if the conditional type has changed then end the old conditional,
|
// if the conditional type has changed then end the old conditional,
|
||||||
// if we were in one, and begin a new one
|
// if we were in one, and begin a new one
|
||||||
if (bytePointer == 0 || newConditional != oldConditional) {
|
if (bytePointer == 0 || newConditional != oldConditional) {
|
||||||
oldConditional = newConditional;
|
oldConditional = newConditional;
|
||||||
FCLInstruction branch;
|
FCLInstruction branch;
|
||||||
branch = FCLInstruction(oldConditional);
|
branch = FCLInstruction(Token::CONDITIONAL);
|
||||||
|
|
||||||
if (bytePointer > 0) {
|
if (bytePointer > 0) {
|
||||||
detokenisedStream += "ENDIF\n";
|
detokenisedStream += "ENDIF\n";
|
||||||
@ -86,18 +88,23 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
|
|||||||
}
|
}
|
||||||
|
|
||||||
branch.setBranches(conditionalInstructions, nullptr);
|
branch.setBranches(conditionalInstructions, nullptr);
|
||||||
|
branch.setSource(oldConditional); // conditional flag
|
||||||
instructions.push_back(branch);
|
instructions.push_back(branch);
|
||||||
|
|
||||||
if (oldConditional == Token::SHOTQ)
|
detokenisedStream += "IF ";
|
||||||
detokenisedStream += "IF SHOT? THEN\n";
|
|
||||||
else if (oldConditional == Token::TIMERQ)
|
if (oldConditional & kConditionalShot)
|
||||||
detokenisedStream += "IF TIMER? THEN\n";
|
detokenisedStream += "SHOT? ";
|
||||||
else if (oldConditional == Token::COLLIDEDQ)
|
else if (oldConditional & kConditionalTimeout)
|
||||||
detokenisedStream += "IF COLLIDED? THEN\n";
|
detokenisedStream += "TIMER? ";
|
||||||
else if (oldConditional == Token::ACTIVATEDQ)
|
else if (oldConditional & kConditionalCollided)
|
||||||
detokenisedStream += "IF ACTIVATED? THEN\n";
|
detokenisedStream += "COLLIDED? ";
|
||||||
|
else if (oldConditional & kConditionalActivated)
|
||||||
|
detokenisedStream += "ACTIVATED? ";
|
||||||
else
|
else
|
||||||
error("Invalid conditional: %x", oldConditional);
|
error("Invalid conditional: %x", oldConditional);
|
||||||
|
|
||||||
|
detokenisedStream += "THEN\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the actual operation
|
// get the actual operation
|
||||||
|
@ -36,6 +36,13 @@ enum {
|
|||||||
k8bitVariableEnergyDrillerJet = 57
|
k8bitVariableEnergyDrillerJet = 57
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kConditionalShot = 1 << 0,
|
||||||
|
kConditionalTimeout = 1 << 1,
|
||||||
|
kConditionalCollided = 1 << 2,
|
||||||
|
kConditionalActivated = 1 << 3,
|
||||||
|
};
|
||||||
|
|
||||||
extern uint8 k8bitMaxVariable;
|
extern uint8 k8bitMaxVariable;
|
||||||
extern uint8 k8bitMaxShield;
|
extern uint8 k8bitMaxShield;
|
||||||
extern uint8 k8bitMaxEnergy;
|
extern uint8 k8bitMaxEnergy;
|
||||||
|
@ -148,31 +148,13 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
|
|||||||
debugC(1, kFreescapeDebugCode, "Executing NOP at ip: %d", ip);
|
debugC(1, kFreescapeDebugCode, "Executing NOP at ip: %d", ip);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Token::ACTIVATEDQ:
|
case Token::CONDITIONAL:
|
||||||
if (shot) // TODO: implement interaction
|
if (checkConditional(instruction, shot, collided, timer, false)) // TODO: implement interaction
|
||||||
executeCode(*instruction._thenInstructions, shot, collided, timer);
|
executeCode(*instruction._thenInstructions, shot, collided, timer);
|
||||||
// else branch is always empty
|
// else branch is always empty
|
||||||
assert(instruction._elseInstructions == nullptr);
|
assert(instruction._elseInstructions == nullptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Token::COLLIDEDQ:
|
|
||||||
if (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, 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;
|
|
||||||
case Token::VARNOTEQ:
|
case Token::VARNOTEQ:
|
||||||
if (executeEndIfNotEqual(instruction))
|
if (executeEndIfNotEqual(instruction))
|
||||||
ip = codeSize;
|
ip = codeSize;
|
||||||
@ -355,6 +337,23 @@ bool FreescapeEngine::executeEndIfVisibilityIsEqual(FCLInstruction &instruction)
|
|||||||
return (obj->isInvisible() == (value != 0));
|
return (obj->isInvisible() == (value != 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FreescapeEngine::checkConditional(FCLInstruction &instruction, bool shot, bool collided, bool timer, bool activated) {
|
||||||
|
uint16 conditional = instruction._source;
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (conditional & kConditionalShot)
|
||||||
|
result |= shot;
|
||||||
|
if (conditional & kConditionalTimeout)
|
||||||
|
result |= timer;
|
||||||
|
if (conditional & kConditionalCollided)
|
||||||
|
result |= collided;
|
||||||
|
if (conditional & kConditionalActivated)
|
||||||
|
result |= activated;
|
||||||
|
|
||||||
|
debugC(1, kFreescapeDebugCode, "Check if conditional %x is true: %d!", conditional, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool FreescapeEngine::checkIfGreaterOrEqual(FCLInstruction &instruction) {
|
bool FreescapeEngine::checkIfGreaterOrEqual(FCLInstruction &instruction) {
|
||||||
uint16 variable = instruction._source;
|
uint16 variable = instruction._source;
|
||||||
uint16 value = instruction._destination;
|
uint16 value = instruction._destination;
|
||||||
|
@ -30,12 +30,11 @@ namespace Freescape {
|
|||||||
struct Token {
|
struct Token {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
ACTIVATEDQ,
|
|
||||||
ADDVAR,
|
ADDVAR,
|
||||||
AGAIN,
|
AGAIN,
|
||||||
AND,
|
AND,
|
||||||
ANDV,
|
ANDV,
|
||||||
COLLIDEDQ,
|
CONDITIONAL,
|
||||||
DELAY,
|
DELAY,
|
||||||
DESTROY,
|
DESTROY,
|
||||||
DESTROYEDQ,
|
DESTROYEDQ,
|
||||||
@ -67,7 +66,6 @@ public:
|
|||||||
SCREEN,
|
SCREEN,
|
||||||
SOUND,
|
SOUND,
|
||||||
SETVAR,
|
SETVAR,
|
||||||
SHOTQ,
|
|
||||||
START,
|
START,
|
||||||
STARTANIM,
|
STARTANIM,
|
||||||
STOPANIM,
|
STOPANIM,
|
||||||
@ -75,7 +73,6 @@ public:
|
|||||||
SUBVAR,
|
SUBVAR,
|
||||||
SYNCSND,
|
SYNCSND,
|
||||||
THEN,
|
THEN,
|
||||||
TIMERQ,
|
|
||||||
TOGVIS,
|
TOGVIS,
|
||||||
TRIGANIM,
|
TRIGANIM,
|
||||||
UPDATEI,
|
UPDATEI,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user