Scene::Scene(SagaEngine *vm) : _vm(vm) { ByteArray sceneLUTData; uint32 resourceId; uint i; // Do nothing for SAGA2 games for now if (_vm->isSaga2()) { _inGame = false; _sceneLoaded = false; return; } // Load scene module resource context _sceneContext = _vm->_resource->getContext(GAME_RESOURCEFILE); if (_sceneContext == NULL) { error("Scene::Scene() scene context not found"); } // Load scene lookup table resourceId = _vm->_resource->convertResourceId(_vm->getResourceDescription()->sceneLUTResourceId); debug(3, "Loading scene LUT from resource %i", resourceId); _vm->_resource->loadResource(_sceneContext, resourceId, sceneLUTData); if (sceneLUTData.empty()) { error("Scene::Scene() sceneLUT is empty"); } _sceneLUT.resize(sceneLUTData.size() / 2); ByteArrayReadStreamEndian readS(sceneLUTData, _sceneContext->isBigEndian()); for (i = 0; i < _sceneLUT.size(); i++) { _sceneLUT[i] = readS.readUint16(); debug(8, "sceneNumber %i has resourceId %i", i, _sceneLUT[i]); } #ifdef SAGA_DEBUG #define DUMP_SCENES_LEVEL 10 if (DUMP_SCENES_LEVEL <= gDebugLevel) { int backUpDebugLevel = gDebugLevel; SAGAResourceTypes *types; int typesCount; SAGAResourceTypes resType; SceneResourceDataArray resourceList; getResourceTypes(types, typesCount); for (i = 0; i < _sceneLUT.size(); i++) { gDebugLevel = -1; loadSceneDescriptor(_sceneLUT[i]); loadSceneResourceList(_sceneDescription.resourceListResourceId, resourceList); gDebugLevel = backUpDebugLevel; debug(DUMP_SCENES_LEVEL, "Dump Scene: number %i, descriptor resourceId %i, resourceList resourceId %i", i, _sceneLUT[i], _sceneDescription.resourceListResourceId); debug(DUMP_SCENES_LEVEL, "\tresourceListCount %i", (int)resourceList.size()); for (SceneResourceDataArray::iterator j = resourceList.begin(); j != resourceList.end(); ++j) { if (j->resourceType >= typesCount) { error("wrong resource type %i", j->resourceType); } resType = types[j->resourceType]; debug(DUMP_SCENES_LEVEL, "\t%s resourceId %i", SAGAResourceTypesString[resType], j->resourceId); } } } #endif debug(3, "LUT has %d entries.", _sceneLUT.size()); _sceneLoaded = false; _sceneNumber = 0; _chapterNumber = 0; _sceneResourceId = 0; _inGame = false; _sceneDescription.reset(); _sceneProc = NULL; _objectMap = new ObjectMap(_vm); _actionMap = new ObjectMap(_vm); }
void Scene::loadScene(LoadSceneParams &loadSceneParams) { Event event; EventColumns *eventColumns; static PalEntry current_pal[PAL_ENTRIES]; if (loadSceneParams.transitionType == kTransitionFade) _vm->_interface->setFadeMode(kFadeOut); // Change the cursor to an hourglass in IHNM event.type = kEvTOneshot; event.code = kCursorEvent; event.op = kEventSetBusyCursor; event.time = 0; _vm->_events->queue(event); _chapterPointsChanged = false; #ifdef ENABLE_IHNM if ((_vm->getGameId() == GID_IHNM) && (loadSceneParams.chapter != NO_CHAPTER_CHANGE)) { if (loadSceneParams.loadFlag != kLoadBySceneNumber) { error("loadScene wrong usage"); } if (loadSceneParams.chapter == 6 || loadSceneParams.chapter == 8) _vm->_interface->setLeftPortrait(0); _vm->_anim->clearCutawayList(); _vm->_script->clearModules(); // deleteAllScenes(); // installSomeAlarm() _vm->_interface->clearInventory(); _vm->_resource->loadGlobalResources(loadSceneParams.chapter, loadSceneParams.actorsEntrance); _vm->_interface->addToInventory(IHNM_OBJ_PROFILE); _vm->_interface->activate(); if (loadSceneParams.chapter == 8 || loadSceneParams.chapter == -1) { if (!_vm->isIHNMDemo()) _vm->_interface->setMode(kPanelChapterSelection); else _vm->_interface->setMode(kPanelNull); } else { _vm->_interface->setMode(kPanelMain); } _inGame = true; _vm->_script->setVerb(_vm->_script->getVerbType(kVerbWalkTo)); if (loadSceneParams.sceneDescriptor == -2) { _vm->_interface->setFadeMode(kNoFade); return; } } #endif if (_sceneLoaded) { error("Scene::loadScene(): Error, a scene is already loaded"); } #ifdef ENABLE_IHNM if (_vm->getGameId() == GID_IHNM) { if (loadSceneParams.loadFlag == kLoadBySceneNumber) // When will we get rid of it? if (loadSceneParams.sceneDescriptor <= 0) loadSceneParams.sceneDescriptor = _vm->_resource->getMetaResource()->sceneIndex; } #endif switch (loadSceneParams.loadFlag) { case kLoadByResourceId: _sceneNumber = 0; // original assign zero for loaded by resource id _sceneResourceId = loadSceneParams.sceneDescriptor; break; case kLoadBySceneNumber: _sceneNumber = loadSceneParams.sceneDescriptor; _sceneResourceId = getSceneResourceId(_sceneNumber); break; } debug(3, "Loading scene number %d:", _sceneNumber); if (isNonInteractiveIHNMDemoPart()) { // WORKAROUND for the non-interactive part of the IHNM demo: When restarting the // non-interactive demo, opcode sfMainMode is incorrectly called. Therefore, if any // of the scenes of the non-interactive demo are loaded (scenes 144-149), set panel // to null and lock the user interface _vm->_interface->deactivate(); _vm->_interface->setMode(kPanelNull); } // Load scene descriptor and resource list resources debug(3, "Loading scene resource %i", _sceneResourceId); loadSceneDescriptor(_sceneResourceId); SceneResourceDataArray resourceList; loadSceneResourceList(_sceneDescription.resourceListResourceId, resourceList); // Process resources from scene resource list processSceneResources(resourceList); if (_sceneDescription.flags & kSceneFlagISO) { _outsetSceneNumber = _sceneNumber; _sceneClip.left = 0; _sceneClip.top = 0; _sceneClip.right = _vm->getDisplayInfo().width; _sceneClip.bottom = getHeight(); } else { BGInfo backGroundInfo; getBGInfo(backGroundInfo); _sceneClip = backGroundInfo.bounds; if (!(_bg.w < _vm->getDisplayInfo().width || _bg.h < getHeight())) _outsetSceneNumber = _sceneNumber; } _sceneLoaded = true; eventColumns = NULL; if (loadSceneParams.transitionType == kTransitionFade) { _vm->_interface->setFadeMode(kFadeOut); // Fade to black out _vm->_gfx->getCurrentPal(current_pal); event.type = kEvTImmediate; event.code = kPalEvent; event.op = kEventPalToBlack; event.time = 0; event.duration = kNormalFadeDuration; event.data = current_pal; eventColumns = _vm->_events->queue(event); // set fade mode event.type = kEvTImmediate; event.code = kInterfaceEvent; event.op = kEventSetFadeMode; event.param = kNoFade; event.time = 0; event.duration = 0; _vm->_events->chain(eventColumns, event); // Display scene background, but stay with black palette event.type = kEvTImmediate; event.code = kBgEvent; event.op = kEventDisplay; event.param = kEvPNoSetPalette; event.time = 0; event.duration = 0; _vm->_events->chain(eventColumns, event); } // Start the scene pre script, but stay with black palette if (_sceneDescription.startScriptEntrypointNumber > 0) { event.type = kEvTOneshot; event.code = kScriptEvent; event.op = kEventExecBlocking; event.time = 0; event.param = _sceneDescription.scriptModuleNumber; event.param2 = _sceneDescription.startScriptEntrypointNumber; event.param3 = 0; // Action event.param4 = _sceneNumber; // Object event.param5 = loadSceneParams.actorsEntrance; // With Object event.param6 = 0; // Actor eventColumns = _vm->_events->chain(eventColumns, event); } if (loadSceneParams.transitionType == kTransitionFade) { // set fade mode event.type = kEvTImmediate; event.code = kInterfaceEvent; event.op = kEventSetFadeMode; event.param = kFadeIn; event.time = 0; event.duration = 0; eventColumns = _vm->_events->chain(eventColumns, event); // Fade in from black to the scene background palette event.type = kEvTImmediate; event.code = kPalEvent; event.op = kEventBlackToPal; event.time = 0; event.duration = kNormalFadeDuration; event.data = _bg.pal; _vm->_events->chain(eventColumns, event); // set fade mode event.type = kEvTImmediate; event.code = kInterfaceEvent; event.op = kEventSetFadeMode; event.param = kNoFade; event.time = 0; event.duration = 0; _vm->_events->chain(eventColumns, event); } if (loadSceneParams.sceneProc == NULL) { if (!_inGame && _vm->getGameId() == GID_ITE) { _inGame = true; _vm->_interface->setMode(kPanelMain); } _vm->_sound->stopAll(); if (_vm->getGameId() == GID_ITE) { if (_sceneDescription.musicResourceId >= 0) { _vm->_events->queueMusic(_sceneDescription.musicResourceId); } else { event.type = kEvTOneshot; event.code = kMusicEvent; event.op = kEventStop; event.time = 0; _vm->_events->queue(event); } } // Set scene background event.type = kEvTOneshot; event.code = kBgEvent; event.op = kEventDisplay; event.param = kEvPSetPalette; event.time = 0; _vm->_events->queue(event); // Begin palette cycle animation if present event.type = kEvTOneshot; event.code = kPalAnimEvent; event.op = kEventCycleStart; event.time = 0; _vm->_events->queue(event); // Start the scene main script if (_sceneDescription.sceneScriptEntrypointNumber > 0) { event.type = kEvTOneshot; event.code = kScriptEvent; event.op = kEventExecNonBlocking; event.time = 0; event.param = _sceneDescription.scriptModuleNumber; event.param2 = _sceneDescription.sceneScriptEntrypointNumber; event.param3 = _vm->_script->getVerbType(kVerbEnter); // Action event.param4 = _sceneNumber; // Object event.param5 = loadSceneParams.actorsEntrance; // With Object event.param6 = 0; // Actor _vm->_events->queue(event); } debug(3, "Scene started"); } else { loadSceneParams.sceneProc(SCENE_BEGIN, this); } // We probably don't want "followers" to go into scene -1 , 0. At the very // least we don't want garbage to be drawn that early in the ITE intro. if (_sceneNumber > 0 && _sceneNumber != ITE_SCENE_PUZZLE) _vm->_actor->updateActorsScene(loadSceneParams.actorsEntrance); if (_sceneNumber == ITE_SCENE_PUZZLE) _vm->_puzzle->execute(); if (getFlags() & kSceneFlagShowCursor) { // Activate user interface event.type = kEvTOneshot; event.code = kInterfaceEvent; event.op = kEventActivate; event.time = 0; _vm->_events->queue(event); } // Change the cursor back to a crosshair in IHNM event.type = kEvTOneshot; event.code = kCursorEvent; event.op = kEventSetNormalCursor; event.time = 0; _vm->_events->queue(event); }
Scene::Scene(SagaEngine *vm) : _vm(vm) { byte *sceneLUTPointer; size_t sceneLUTLength; uint32 resourceId; int i; // Do nothing for SAGA2 games for now if (_vm->isSaga2()) { _inGame = false; _sceneLoaded = false; return; } // Load scene module resource context _sceneContext = _vm->_resource->getContext(GAME_RESOURCEFILE); if (_sceneContext == NULL) { error("Scene::Scene() scene context not found"); } // Load scene lookup table resourceId = _vm->_resource->convertResourceId(_vm->getResourceDescription()->sceneLUTResourceId); debug(3, "Loading scene LUT from resource %i", resourceId); _vm->_resource->loadResource(_sceneContext, resourceId, sceneLUTPointer, sceneLUTLength); if (sceneLUTLength == 0) { error("Scene::Scene() sceneLUTLength == 0"); } _sceneCount = sceneLUTLength / 2; _sceneLUT = (int *)malloc(_sceneCount * sizeof(*_sceneLUT)); if (_sceneLUT == NULL) { memoryError("Scene::Scene()"); } MemoryReadStreamEndian readS(sceneLUTPointer, sceneLUTLength, _sceneContext->isBigEndian); for (i = 0; i < _sceneCount; i++) { _sceneLUT[i] = readS.readUint16(); debug(8, "sceneNumber %i has resourceId %i", i, _sceneLUT[i]); } free(sceneLUTPointer); #ifdef SAGA_DEBUG #define DUMP_SCENES_LEVEL 10 if (DUMP_SCENES_LEVEL <= gDebugLevel) { uint j; int backUpDebugLevel = gDebugLevel; SAGAResourceTypes *types; int typesCount; SAGAResourceTypes resType; getResourceTypes(types, typesCount); for (i = 0; i < _sceneCount; i++) { gDebugLevel = -1; loadSceneDescriptor(_sceneLUT[i]); loadSceneResourceList(_sceneDescription.resourceListResourceId); gDebugLevel = backUpDebugLevel; debug(DUMP_SCENES_LEVEL, "Dump Scene: number %i, descriptor resourceId %i, resourceList resourceId %i", i, _sceneLUT[i], _sceneDescription.resourceListResourceId); debug(DUMP_SCENES_LEVEL, "\tresourceListCount %i", (int)_resourceListCount); for (j = 0; j < _resourceListCount; j++) { if (_resourceList[j].resourceType >= typesCount) { error("wrong resource type %i", _resourceList[j].resourceType); } resType = types[_resourceList[j].resourceType]; debug(DUMP_SCENES_LEVEL, "\t%s resourceId %i", SAGAResourceTypesString[resType], _resourceList[j].resourceId); } free(_resourceList); } } #endif debug(3, "LUT has %d entries.", _sceneCount); _sceneLoaded = false; _sceneNumber = 0; _chapterNumber = 0; _sceneResourceId = 0; _inGame = false; _loadDescription = false; memset(&_sceneDescription, 0, sizeof(_sceneDescription)); _resourceListCount = 0; _resourceList = NULL; _sceneProc = NULL; _objectMap = new ObjectMap(_vm); _actionMap = new ObjectMap(_vm); memset(&_bg, 0, sizeof(_bg)); memset(&_bgMask, 0, sizeof(_bgMask)); }