コード例 #1
0
ファイル: saveload.cpp プロジェクト: MathiasBartl/scummvm
/**
 * Load animDataTable from save
 * @param fHandle Savefile open for reading
 * @param saveGameFormat The used savegame format
 * @todo Add Operation Stealth savefile support
 *
 * Unlike the old code, this one actually rebuilds the table one frame
 * at a time.
 */
void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGameFormat saveGameFormat) {
    int16 foundFileIdx;
    char *animName, part[256], name[10];

    strcpy(part, currentPartName);

    // We only support these variations of the savegame format at the moment.
    assert(saveGameFormat == ANIMSIZE_23 || saveGameFormat == ANIMSIZE_30_PTRS_INTACT);

    const int entrySize = ((saveGameFormat == ANIMSIZE_23) ? 23 : 30);
    const int fileStartPos = fHandle.pos();

    for(int resourceIndex=0; resourceIndex<NUM_MAX_ANIMDATA; resourceIndex++) {
        // Seek to the start of the current animation's entry
        fHandle.seek(fileStartPos + resourceIndex * entrySize);
        // Read in the current animation entry
        fHandle.readUint16BE(); // width
        fHandle.readUint16BE();
        fHandle.readUint16BE(); // bpp
        fHandle.readUint16BE(); // height

        bool validPtr = false;
        // Handle variables only present in animation entries of size 30
        if (entrySize == 30) {
            validPtr = (fHandle.readUint32BE() != 0); // Read data pointer
            fHandle.readUint32BE(); // Discard mask pointer
        }

        foundFileIdx = fHandle.readSint16BE();
        int16 frameIndex = fHandle.readSint16BE(); // frame
        fHandle.read(name, 10);

        // Handle variables only present in animation entries of size 23
        if (entrySize == 23) {
            validPtr = (fHandle.readByte() != 0);
        }

        // Don't try to load invalid entries.
        if (foundFileIdx < 0 || !validPtr) {
            //resourceIndex++; // Jump over the invalid entry
            continue;
        }

        // Alright, the animation entry looks to be valid so let's start handling it...
        if (strcmp(currentPartName, name) != 0) {
            closePart();
            loadPart(name);
        }

        animName = g_cine->_partBuffer[foundFileIdx].partName;
        loadRelatedPalette(animName); // Is this for Future Wars only?
        loadResource(animName, resourceIndex, frameIndex);
    }

    loadPart(part);

    // Make sure we jump over all the animation entries
    fHandle.seek(fileStartPos + NUM_MAX_ANIMDATA * entrySize);
}
コード例 #2
0
ファイル: main_loop.cpp プロジェクト: St0rmcrow/scummvm
void CineEngine::mainLoop(int bootScriptIdx) {
	bool playerAction;
	byte di;
	uint16 mouseButton;

	if (_preLoad == false) {
		resetBgIncrustList();

		setTextWindow(0, 0, 20, 200);

		errorVar = 0;

		addScriptToGlobalScripts(bootScriptIdx);

		menuVar = 0;

//		gfxRedrawPage(page0c, page0, page0c, page0, -1);
//		gfxWaitVBL();
//		gfxRedrawMouseCursor();

		inMenu = false;
		allowPlayerInput = 0;
		checkForPendingDataLoadSwitch = 0;

		fadeRequired = false;
		isDrawCommandEnabled = 0;
		waitForPlayerClick = 0;
		menuCommandLen = 0;

		playerCommand = -1;
		g_cine->_commandBuffer = "";

		g_cine->_globalVars[VAR_MOUSE_X_POS] = 0;
		g_cine->_globalVars[VAR_MOUSE_Y_POS] = 0;
		if (g_cine->getGameType() == Cine::GType_OS) {
			g_cine->_globalVars[VAR_MOUSE_X_POS_2ND] = 0;
			g_cine->_globalVars[VAR_MOUSE_Y_POS_2ND] = 0;
			g_cine->_globalVars[VAR_BYPASS_PROTECTION] = 0; // set to 1 to bypass the copy protection
			g_cine->_globalVars[VAR_LOW_MEMORY] = 0; // set to 1 to disable some animations, sounds etc.
		}

		strcpy(newPrcName, "");
		strcpy(newRelName, "");
		strcpy(newObjectName, "");
		strcpy(newMsgName, "");
		strcpy(currentCtName, "");
		strcpy(currentPartName, "");

		g_sound->stopMusic();
	}

	do {
		// HACK: Force amount of oxygen left to maximum during Operation Stealth's first arcade sequence.
		//       This makes it possible to pass the arcade sequence for now.
		// FIXME: Remove the hack and make the first arcade sequence normally playable.
		if (g_cine->getGameType() == Cine::GType_OS) {
			Common::String bgName(renderer->getBgName());
			// Check if the background is one of the three backgrounds
			// that are only used during the first arcade sequence.
			if (bgName == "28.PI1" || bgName == "29.PI1" || bgName == "30.PI1") {
				static const uint oxygenObjNum = 202, maxOxygen = 264;
				// Force the amount of oxygen left to the maximum.
				g_cine->_objectTable[oxygenObjNum].x = maxOxygen;
			}
		}

		// HACK: In Operation Stealth after the first arcade sequence jump player's position to avoid getting stuck.
		// After the first arcade sequence the player comes up stairs from
		// the water in Santa Paragua's downtown in front of the flower shop.
		// Previously he was completely stuck after getting up the stairs.
		// If the background is the one used in the flower shop scene ("21.PI1")
		// and the player is at the exact location after getting up the stairs
		// then we just nudge him a tiny bit away from the stairs and voila, he's free!
		// Maybe the real problem behind all this is collision data related as it looks
		// like there's some boundary right there near position (204, 110) which we can
		// jump over by moving the character to (204, 109). The script handling the
		// flower shop scene is AIRPORT.PRC's 13th script.
		// FIXME: Remove the hack and solve what's really causing the problem in the first place.
		if (g_cine->getGameType() == Cine::GType_OS) {
			if (scumm_stricmp(renderer->getBgName(), "21.PI1") == 0 && g_cine->_objectTable[1].x == 204 && g_cine->_objectTable[1].y == 110) {
				g_cine->_objectTable[1].y--; // Move the player character upward on-screen by one pixel
			}
		}

		stopMusicAfterFadeOut();
		di = executePlayerInput();

		// Clear the zoneQuery table (Operation Stealth specific)
		if (g_cine->getGameType() == Cine::GType_OS) {
			Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
		}

		if (g_cine->getGameType() == Cine::GType_OS) {
			processSeqList();
		}
		executeObjectScripts();
		executeGlobalScripts();

		purgeObjectScripts();
		purgeGlobalScripts();
		if (g_cine->getGameType() == Cine::GType_OS) {
			purgeSeqList();
		}

		if (playerCommand == -1) {
			setMouseCursor(MOUSE_CURSOR_NORMAL);
		} else {
			setMouseCursor(MOUSE_CURSOR_CROSS);
		}

		if (renderer->ready()) {
			renderer->drawFrame();
		}

		// NOTE: In the original Future Wars and Operation Stealth messages
		// were removed when running the drawOverlays function which is
		// currently called from the renderer's drawFrame function.
		removeMessages();

		if (waitForPlayerClick) {
			playerAction = false;

			_messageLen <<= 3;
			if (_messageLen < 0x800)
				_messageLen = 0x800;

			do {
				manageEvents();
				getMouseData(mouseUpdateStatus, &mouseButton, &dummyU16, &dummyU16);
			} while (mouseButton != 0 && !shouldQuit());

			menuVar = 0;

			do {
				manageEvents();
				getMouseData(mouseUpdateStatus, &mouseButton, &dummyU16, &dummyU16);
				playerAction = (mouseButton != 0) || processKeyboard(menuVar);
				mainLoopSub6();
			} while (!playerAction && !shouldQuit());

			menuVar = 0;

			do {
				manageEvents();
				getMouseData(mouseUpdateStatus, &mouseButton, &dummyU16, &dummyU16);
			} while (mouseButton != 0 && !shouldQuit());

			waitForPlayerClick = 0;
		}

		if (checkForPendingDataLoadSwitch) {
			checkForPendingDataLoad();

			checkForPendingDataLoadSwitch = 0;
		}

		if (di) {
			if ("quit"[menuCommandLen] == (char)di) {
				++menuCommandLen;
				if (menuCommandLen == 4) {
					quitGame();
				}
			} else {
				menuCommandLen = 0;
			}
		}

		manageEvents();

	} while (!shouldQuit() && !_restartRequested);

	hideMouse();
	g_sound->stopMusic();
	// if (g_cine->getGameType() == Cine::GType_OS) {
	//	freeUnkList();
	// }
	closePart();
}