예제 #1
0
파일: parser_scn.cpp 프로젝트: cyxx/bermuda
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;
}
예제 #2
0
파일: game.cpp 프로젝트: raziel-/bermuda
void Game::mainLoop() {
	if (_nextState != _state) {
		// fini
		switch (_state) {
		case kStateGame:
			break;
		case kStateDialogue:
			finiDialogue();
			break;
		case kStateMenu1:
		case kStateMenu2:
			finiMenu();
			break;
		}
		_state = _nextState;
		// init
		switch (_state) {
		case kStateGame:
			break;
		case kStateDialogue:
			initDialogue();
			break;
		case kStateBitmap:
			displayTitleBitmap();
			break;
		case kStateMenu1:
		case kStateMenu2:
			initMenu(1 + _state - kStateMenu1);
			break;
		}
	}
	switch (_state) {
	case kStateGame:
		while (_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 {
				debug(DBG_GAME, "load mov '%s'", _tempTextBuffer);
				loadMOV(_tempTextBuffer);
			}
			if (_loadState) {
				_loadState = false;
				if (_currentSceneSav[0]) {
					FileHolder fh(_fs, _currentSceneSav);
					if (!fh._fp) {
						warning("Unable to load game state from file '%s'", _tempTextBuffer);
					} else {
						warning("Loading game state from '%s'", _currentSceneSav);
						loadState(fh._fp, kDemoSavSlot, false);
						loadKBR(_currentSceneSav);
					}
				} else {
					char filePath[MAXPATHLEN];
					snprintf(filePath, sizeof(filePath), kGameStateFileNameFormat, _savePath, _stateSlot);
					File f;
					if (!f.open(filePath, "rb")) {
						warning("Unable to load game state from file '%s'", filePath);
					} else {
						loadState(&f, _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) {
				_stub->setPalette(_bitmapBuffer0 + kOffsetBitmapPalette, 256);
				_stub->copyRectWidescreen(kGameScreenWidth, kGameScreenHeight, _bitmapBuffer1.bits, _bitmapBuffer1.pitch);
			}
			_gameOver = false;
			_workaroundRaftFlySceneBug = strncmp(_currentSceneScn, "FLY", 3) == 0;
		}
		updateKeysPressedTable();
		updateMouseButtonsPressed();
		runObjectsScript();
		if (_startDialogue) {
			_startDialogue = false;
			_nextState = kStateDialogue;
		}
		break;
	case kStateBag:
		handleBagMenu();
		break;
	case kStateDialogue:
		handleDialogue();
		if (_dialogueEndedFlag) {
			_nextState = kStateGame;
		}
		break;
	case kStateBitmap:
		if (_stub->_pi.enter) {
			_stub->_pi.enter = false;
			playVideo("DATA/INTRO.AVI");
			_nextState = kStateGame;
		}
		break;
	case kStateMenu1:
		handleMenu();
		switch (_menuOption) {
		case kMenuOptionNewGame:
			restart();
			_nextState = kStateGame;
			break;
		case kMenuOptionLoadGame:
			_stub->_pi.load = true;
			_nextState = kStateGame;
			break;
		case kMenuOptionSaveGame:
			_stub->_pi.save = true;
			_nextState = kStateGame;
			break;
		case kMenuOptionQuitGame:
			_nextState = kStateMenu2;
			break;
		}
		if (_stub->_pi.escape) {
			_stub->_pi.escape = false;
			_nextState = kStateGame;
		}
		break;
	case kStateMenu2:
		handleMenu();
		switch (_menuOption) {
		case kMenuOptionExitGame:
			_stub->_quit = true;
			break;
		case kMenuOptionReturnGame:
			_nextState = kStateGame;
			break;
		}
		if (_stub->_pi.escape) {
			_stub->_pi.escape = false;
			_nextState = kStateGame;
		}
		break;
	}
	_stub->updateScreen();
}
예제 #3
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();
}