Ejemplo n.º 1
0
void Game::runObjectsScript() {
	debug(DBG_GAME, "Game::runObjectsScript()");
	_objectScript.nextScene = -1;
	assert(_loadDataState != 3); // unneeded code
	if (_varsTable[309]) {
		memset(_keysPressed, 0, sizeof(_keysPressed));
	}
	if (_loadDataState == 2) {
		int start = _workaroundRaftFlySceneBug ? 1 : 0;
		_workaroundRaftFlySceneBug = false;
		for (int i = start; i < _sceneObjectsCount; ++i) {
			SceneObject *so = &_sceneObjectsTable[i];
			if (so->statePrev == 0 || so->statePrev == -1) {
				continue;
			}
			debug(DBG_GAME, "Game::runObjectsScript() currentObjectNum=%d", i);
			_objectScript.currentObjectNum = i;
			int anim = _sceneObjectMotionsTable[so->motionNum1].animNum;
			assert(anim >= 0 && anim < _animationsCount);
			_objectScript.data = _animationsTable[anim].scriptData;
			int endOfDataOffset = _animationsTable[anim].scriptSize; // endOfDataOffset2
			_objectScript.dataOffset = 0;
			int statement = 0;
			while (_objectScript.dataOffset < endOfDataOffset) {
				_objectScript.statementNum = statement;
				int endOfStatementDataOffset = _objectScript.fetchNextWord(); // endOfDataOffset1
				_objectScript.testObjectNum = -1;
				_objectScript.testDataOffset = endOfStatementDataOffset;
				bool loop = true;
				while (loop) {
					int op = _objectScript.fetchNextWord();
					debug(DBG_OPCODES, "statement %d condition %d op %d", statement, i, op);
					if (op == 0) {
						break;
					}
					loop = executeConditionOpcode(op);
				}
				if (loop) {
					while (_objectScript.dataOffset < endOfStatementDataOffset) {
						int op = _objectScript.fetchNextWord();
						debug(DBG_OPCODES, "statement %d operator %d op %d", statement, i, op);
						if (op == 100) { // &Game::oop_breakObjectScript
							endOfStatementDataOffset = _objectScript.dataOffset = endOfDataOffset;
							break;
						}
						executeOperatorOpcode(op);
					}
				}
				_objectScript.dataOffset = endOfStatementDataOffset;
				++statement;
			}
		}
		_dialogueEndedFlag = 0;
		if (_objectScript.nextScene != -1 && _objectScript.nextScene < _sceneConditionsCount) {
			strcpy(_tempTextBuffer, _nextScenesTable[_objectScript.nextScene].name);
			_switchScene = true;
			_currentSceneSav[0] = 0;
			if (stringEndsWith(_tempTextBuffer, "SAV")) {

				// debug(DBG_GAME, "End of demo interactive part");
				// strcpy(_tempTextBuffer, "A03.SCN");

				FileHolder fh(_fs, _tempTextBuffer);
				if (!fh._fp) {
					warning("Unable to load game state from file '%s'", _tempTextBuffer);
				} else {
					strcpy(_currentSceneSav, _tempTextBuffer);
					loadState(fh._fp, kDemoSavSlot, true);
					_loadState = _switchScene; // load on scene switch
				}
			}
		}
		for (int i = 0; i < _sceneObjectsCount; ++i) {
			reinitializeObject(i);
		}
		if (kCheatNoHit) {
			_varsTable[0] = 0;
		}
		if (_varsTable[0] >= 10 && !_gameOver) {
			strcpy(_musicName, "..\\midi\\gameover.mid");
			playMusic(_musicName);
			_gameOver = true;
//			_skipUpdateScreen = false;
		}
		if (_loadDataState == 2) {
			updateObjects();
		}
	}
//	_skipUpdateScreen = false;
	if (_varsTable[241] == 1) {
//		_startEndingScene = true;
		stopMusic();
		clearSceneData(-1);
		_varsTable[241] = 2;
		playVideo("DATA/FINAL.AVI");
		strcpy(_tempTextBuffer, "END.SCN");
		_switchScene = true;
	}
}
Ejemplo n.º 2
0
void Game::fini() {
	clearSceneData(-1);
	deallocateTables();
	unloadCommonSprites();
	_stub->destroy();
}
Ejemplo n.º 3
0
void Game::runObjectsScript() {
	debug(DBG_GAME, "Game::runObjectsScript()");
	_objectScript.nextScene = -1;
	assert(_loadDataState != 3); // unneeded code
	if (_varsTable[309]) {
		memset(_keysPressed, 0, sizeof(_keysPressed));
	}
	if (_loadDataState == 2) {
		int start = _workaroundRaftFlySceneBug ? 1 : 0;
		_workaroundRaftFlySceneBug = false;
		for (int i = start; i < _sceneObjectsCount; ++i) {
			SceneObject *so = &_sceneObjectsTable[i];
			if (so->statePrev == 0 || so->statePrev == -1) {
				continue;
			}
			debug(DBG_GAME, "Game::runObjectsScript() currentObjectNum=%d", i);
			_objectScript.currentObjectNum = i;
			int anim = _sceneObjectMotionsTable[so->motionNum1].animNum;
			assert(anim >= 0 && anim < _animationsCount);
			_objectScript.data = _animationsTable[anim].scriptData;
			int endOfDataOffset = _animationsTable[anim].scriptSize; // endOfDataOffset2
			_objectScript.dataOffset = 0;
			int statement = 0;
			while (_objectScript.dataOffset < endOfDataOffset) {
				_objectScript.statementNum = statement;
				int endOfStatementDataOffset = _objectScript.fetchNextWord(); // endOfDataOffset1
				_objectScript.testObjectNum = -1;
				_objectScript.testDataOffset = endOfStatementDataOffset;
				bool loop = true;
				while (loop) {
					int op = _objectScript.fetchNextWord();
					debug(DBG_OPCODES, "statement %d condition %d op %d", statement, i, op);
					if (op == 0) {
						break;
					}
					const GameConditionOpcode *cop = findConditionOpcode(op);
					if (!cop) {
						error("Invalid condition %d", op);
					}
					loop = (this->*(cop->pf))();
				}
				if (loop) {
					while (_objectScript.dataOffset < endOfStatementDataOffset) {
						int op = _objectScript.fetchNextWord();
						debug(DBG_OPCODES, "statement %d operator %d op %d", statement, i, op);
						if (op == 100) { // &Game::oop_breakObjectScript
							endOfStatementDataOffset = _objectScript.dataOffset = endOfDataOffset;
							break;
						}
						const GameOperatorOpcode *oop = findOperatorOpcode(op);
						if (!oop) {
							error("Invalid operator %d", op);
						}
						(this->*(oop->pf))();
					}
				}
				_objectScript.dataOffset = endOfStatementDataOffset;
				++statement;
			}
		}
		_dialogueEndedFlag = 0;
		if (_objectScript.nextScene != -1 && _objectScript.nextScene < _sceneConditionsCount) {
			strcpy(_tempTextBuffer, _nextScenesTable[_objectScript.nextScene].name);
			_switchScene = true;
		}
		for (int i = 0; i < _sceneObjectsCount; ++i) {
			reinitializeObject(i);
		}
#if 0 // cheat: no hit
		_varsTable[0] = 0;
#endif
		if (_varsTable[0] >= 10 && !_gameOver) {
			strcpy(_musicName, "..\\midi\\gameover.mid");
			playMusic(_musicName);
			_gameOver = true;
//			_skipUpdateScreen = false;
		}
		if (_loadDataState == 2) {
			updateObjects();
		}
	}
//	_skipUpdateScreen = false;
	if (_varsTable[241] == 1) {
//		_startEndingScene = true;
		stopMusic();
		clearSceneData(-1);
		_varsTable[241] = 2;
		playVideo("DATA/FINAL.AVI");
		strcpy(_tempTextBuffer, "END.SCN");
		_switchScene = true;
	}
}
Ejemplo n.º 4
0
void Game::parseSCN(const char *fileName) {
	debug(DBG_GAME, "Game::parseSCN()");

	FileHolder fp(_fs, fileName);
	_sceneDescriptionSize = fp->size();
	_sceneDescriptionBuffer = (char *)malloc(_sceneDescriptionSize + 1);
	if (!_sceneDescriptionBuffer) {
		error("Unable to allocate %d bytes", _sceneDescriptionSize + 1);
	}
	fp->read(_sceneDescriptionBuffer, _sceneDescriptionSize);
	_sceneDescriptionBuffer[_sceneDescriptionSize] = 0;
	stringStripComments(_sceneDescriptionBuffer);

	int anim = 0;
	bool loadMovData = false;
	_sceneNumber = 0;
	_currentSceneObject = 0;
	memcpy(_defaultVarsTable, _varsTable, sizeof(_varsTable));

	_currentState = kParserStateDef;
	_stopParsing = false;
	for (char *s = _sceneDescriptionBuffer; !_stopParsing && s; ) {
		bool didTest = false;
		bool compareTest = true;
		while ((_currentToken = getNextToken(&s)) == kParserTokenGlobalMemory) {
			compareTest = compareTest && parseToken_GlobalMemory(&s, this);
			didTest = true;
		}
		if (didTest) {
			if (!compareTest) {
				// condition statement is false, skip to next line
				stringNextTokenEOL(&s);
				continue;
			}
			if (_currentToken != kParserTokenThen) {
				error("Unexpected token %d", _currentToken);
			}
			_currentToken = getNextToken(&s);
		}
		if (_currentState != kParserStateDef) {
			switch (_currentState) {
			case kParserStateMovies:
				if (_currentToken == kParserTokenMoviesEnd) {
					if (!loadMovData) {
						clearSceneData(anim - 1);
					}
					_currentState = kParserStateDef;
				} else {
					if (!loadMovData) {
						if (anim < _animationsCount && strcasecmp(_animationsTable[anim].name, _currentTokenStr) == 0) {
							++anim;
						} else {
							if (_animationsCount != 0) {
								clearSceneData(anim - 1);
							}
							_loadDataState = 1;
							loadMovData = true;
						}
					}
					if (loadMovData) {
						loadMOV(_currentTokenStr);
					}
				}
				break;
			case kParserStateBag:
				if (_currentToken == kParserTokenBagEnd) {
					_currentState = kParserStateDef;
				} else {
					parse_BagObject(&s, this);
				}
				break;
			case kParserStateScene:
				if (_currentToken == kParserTokenSceneEnd) {
					_currentState = kParserStateDef;
				} else {
					parse_SceneCondition(&s, this);
				}
				break;
			case kParserStateObject:
				if (_currentToken == kParserTokenObjectEnd) {
					_currentState = kParserStateDef;
				} else {
					parse_Object(&s, this);
				}
				break;
			case kParserStateNewObject:
				if (_currentToken == kParserTokenObjectEnd) {
					_currentState = kParserStateDef;
				} else {
					if (_currentSceneObject) {
						if (_sceneObjectMotionsTable[_currentSceneObject->motionInit].animNum < anim) {
							_currentSceneObject = 0;
						}
					}
					parse_Object(&s, this);
				}
				break;
			case kParserStateBox:
				if (_currentToken == kParserTokenBoxEnd) {
					_currentState = kParserStateDef;
				} else {
					parse_BoxDescription(&s, this);
				}
				break;
			}
		} else {
			switch (_currentToken) {
			case kParserTokenEnd:
				_stopParsing = true;
				break;
			case kParserTokenMovies:
				_currentState = kParserStateMovies;
				break;
			case kParserTokenScene:
				_currentState = kParserStateScene;
				break;
			case kParserTokenScreen:
				parseToken_Screen(&s, this);
				break;
			case kParserTokenSceneNumber:
				getNextToken_Int(&s, &_sceneNumber);
				break;
			case kParserTokenMidi:
				parseToken_Midi(&s, this);
				break;
			case kParserTokenObject:
				_currentState = kParserStateObject;
				parseToken_Object(&s, this);
				break;
			case kParserTokenIfNewObject:
				_currentState = kParserStateNewObject;
				parseToken_Object(&s, this);
				break;
			case kParserTokenBag:
				_currentState = kParserStateBag;
				parseToken_Bag(&s, this);
				break;
			case kParserTokenBox:
				_currentState = kParserStateBox;
				break;
			default:
				error("Unexpected token %d state %d", _currentToken, _currentState);
				break;
			}
		}
	}

	free(_sceneDescriptionBuffer);
	_sceneDescriptionBuffer = 0;
	_sceneDescriptionSize = 0;
}
Ejemplo n.º 5
0
void Game::mainLoop() {
	_stub->init(_gameWindowTitle, kGameScreenWidth, kGameScreenHeight);
	allocateTables();
	loadCommonSprites();
	_mixer->open();
	restart();
	if (_isDemo) {
		playBitmapSequenceDemo();
	} else {
		playVideo("DATA/LOGO.AVI");
		playVideo("DATA/INTRO.AVI");
	}
	_lastFrameTimeStamp = _stub->getTimeStamp();
	while (!_stub->_quit) {
		if (_switchScene) {
			_switchScene = false;
			if (stringEndsWith(_tempTextBuffer, "SCN")) {
				win16_sndPlaySound(6);
				debug(DBG_GAME, "switch to scene '%s'", _tempTextBuffer);
				if (strcmp(_tempTextBuffer, "PIC4.SCN") == 0) {
					debug(DBG_INFO, "End of game");
					break;
				}
				strcpy(_currentSceneScn, _tempTextBuffer);
				parseSCN(_tempTextBuffer);
			} else if (stringEndsWith(_tempTextBuffer, "SAV")) {
				if (_isDemo && strcmp(_tempTextBuffer, "A16.SAV") == 0) {
					debug(DBG_GAME, "End of demo interactive part");
					restart();
					continue;
				}
				warning("Ignoring savestate load '%s'", _tempTextBuffer);
				// should work though, as the original savestates load fine
				// now, but this "feature" is only used in the demo AFAICT,
				// so no need to bother...
			} else {
				debug(DBG_GAME, "load mov '%s'", _tempTextBuffer);
				loadMOV(_tempTextBuffer);
			}
			if (_loadState) {
				_loadState = false;
				loadState(_stateSlot, false);
				playMusic(_musicName);
				memset(_keysPressed, 0, sizeof(_keysPressed));
			}
			assert(_sceneObjectsCount != 0);
			if (_currentBagObject == -1) {
				_currentBagObject = _bagObjectsCount - 1;
				if (_currentBagObject > 0) {
					_currentBagObject = 0;
				}
			}
			if (_loadDataState != 0) {
				setupScreenPalette(_bitmapBuffer0 + kOffsetBitmapPalette);
			}
			_gameOver = false;
			_workaroundRaftFlySceneBug = strncmp(_currentSceneScn, "FLY", 3) == 0;
		}
		updateKeysPressedTable();
		updateMouseButtonsPressed();
		runObjectsScript();
		if (!_switchScene) {
			_stub->updateScreen();
			uint32 end = _lastFrameTimeStamp + kCycleDelay;
			do {
				_stub->sleep(10);
				_stub->processEvents();
			} while (!_stub->_pi.fastMode && _stub->getTimeStamp() < end);
			_lastFrameTimeStamp = _stub->getTimeStamp();
		}
		if (_startDialogue) {
			_startDialogue = false;
			handleDialogue();
		}
	}
	clearSceneData(-1);
	deallocateTables();
	unloadCommonSprites();
	_mixer->close();
	_stub->destroy();
}