示例#1
0
void HISTORY::save(EMUFILE *os, bool really_save)
{
	if (really_save)
	{
		int real_pos, last_tick = 0;
		// write "HISTORY" string
		os->fwrite(historySaveID, HISTORY_ID_LEN);
		// write vars
		write32le(historyCursorPos, os);
		write32le(historyTotalItems, os);
		// write items starting from history_start_pos
		for (int i = 0; i < historyTotalItems; ++i)
		{
			real_pos = (historyStartPos + i) % historySize;
			snapshots[real_pos].save(os);
			bookmarkBackups[real_pos].save(os);
			os->fwrite(&currentBranchNumberBackups[real_pos], 1);
			if (i / SAVING_HISTORY_PROGRESSBAR_UPDATE_RATE > last_tick)
			{
				playback.setProgressbar(i, historyTotalItems);
				last_tick = i / PROGRESSBAR_UPDATE_RATE;
			}
		}
	} else
	{
		// write "HISTORX" string
		os->fwrite(historySkipSaveID, HISTORY_ID_LEN);
	}
}
示例#2
0
// returns true if couldn't load
bool GREENZONE::load(EMUFILE *is, unsigned int offset)
{
	free();
	if (offset)
	{
		if (is->fseek(offset, SEEK_SET)) goto error;
	} else
	{
		reset();
		playback.restartPlaybackFromZeroGround();		// reset Playback cursor to frame 0
		return false;
	}
	int frame = 0, prev_frame = -1, size = 0;
	int last_tick = 0;
	// read "GREENZONE" string
	char save_id[GREENZONE_ID_LEN];
	if ((int)is->fread(save_id, GREENZONE_ID_LEN) < GREENZONE_ID_LEN) goto error;
	if (!strcmp(greenzone_skipsave_id, save_id))
	{
		// string says to skip loading Greenzone
		// read LagLog
		lagLog.load(is);
		// read Playback cursor position
		if (read32le(&frame, is))
		{
			currFrameCounter = frame;
			greenzoneSize = currFrameCounter + 1;
			savestates.resize(greenzoneSize);
			if (currFrameCounter)
			{
				// there must be one savestate in the file
				if (read32le(&size, is) && size >= 0)
				{
					savestates[frame].resize(size);
					if (is->fread(&savestates[frame][0], size) == size)
					{
						if (loadSavestateOfFrame(currFrameCounter))
						{
							FCEU_printf("No Greenzone in the file\n");
							return false;
						}
					}
				}
			} else
			{
				// literally no Greenzone in the file, but this is still not a error
				reset();
				playback.restartPlaybackFromZeroGround();		// reset Playback cursor to frame 0
				FCEU_printf("No Greenzone in the file, Playback at frame 0\n");
				return false;
			}
		}
		goto error;
	}
	if (strcmp(greenzone_save_id, save_id)) goto error;		// string is not valid
	// read LagLog
	lagLog.load(is);
	// read size
	if (read32le(&size, is) && size >= 0 && size <= currMovieData.getNumRecords())
	{
		greenzoneSize = size;
		savestates.resize(greenzoneSize);
		// read Playback cursor position
		if (read32le(&frame, is))
		{
			currFrameCounter = frame;
			int greenzone_tail_frame = currFrameCounter - taseditorConfig.greenzoneCapacity;
			int greenzone_tail_frame2 = greenzone_tail_frame - 2 * taseditorConfig.greenzoneCapacity;
			int greenzone_tail_frame4 = greenzone_tail_frame - 4 * taseditorConfig.greenzoneCapacity;
			int greenzone_tail_frame8 = greenzone_tail_frame - 8 * taseditorConfig.greenzoneCapacity;
			int greenzone_tail_frame16 = greenzone_tail_frame - 16 * taseditorConfig.greenzoneCapacity;
			// read savestates
			while(1)
			{
				if (!read32le(&frame, is)) break;
				if (frame < 0) break;		// -1 = eof
				// update TASEditor progressbar from time to time
				if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
				{
					playback.setProgressbar(frame, greenzoneSize);
					last_tick = frame / PROGRESSBAR_UPDATE_RATE;
				}
				// read savestate
				if (!read32le(&size, is)) break;
				if (size < 0) break;
				if (frame <= greenzone_tail_frame16
					|| (frame <= greenzone_tail_frame8 && (frame & 0xF))
					|| (frame <= greenzone_tail_frame4 && (frame & 0x7))
					|| (frame <= greenzone_tail_frame2 && (frame & 0x3))
					|| (frame <= greenzone_tail_frame && (frame & 0x1)))
				{
					// skip loading this savestate
					if (is->fseek(size, SEEK_CUR) != 0) break;
				} else
				{
					// load this savestate
					if ((int)savestates.size() <= frame)
						savestates.resize(frame + 1);
					savestates[frame].resize(size);
					if ((int)is->fread(&savestates[frame][0], size) < size) break;
					prev_frame = frame;			// successfully read one Greenzone frame info
				}
			}
			if (prev_frame+1 == greenzoneSize)
			{
				// everything went fine - load savestate at cursor position
				if (loadSavestateOfFrame(currFrameCounter))
					return false;
			}
			// uh, okay, but maybe we managed to read at least something useful from the file
			// first see if original position of currFrameCounter was read successfully
			if (loadSavestateOfFrame(currFrameCounter))
			{
				greenzoneSize = prev_frame+1;		// cut greenZoneCount to last good frame
				FCEU_printf("Greenzone loaded partially\n");
				return false;
			}
			// then at least jump to some frame that was read successfully
			for (; prev_frame >= 0; prev_frame--)
			{
				if (loadSavestateOfFrame(prev_frame))
				{
					currFrameCounter = prev_frame;
					greenzoneSize = prev_frame+1;		// cut greenZoneCount to this good frame
					FCEU_printf("Greenzone loaded partially, Playback moved to the end of greenzone\n");
					return false;
				}
			}
		}
	}
error:
	FCEU_printf("Error loading Greenzone\n");
	reset();
	playback.restartPlaybackFromZeroGround();		// reset Playback cursor to frame 0
	return true;
}
示例#3
0
// returns true if couldn't load
bool HISTORY::load(EMUFILE *is, unsigned int offset)
{
	int i = -1;
	SNAPSHOT snap;
	BOOKMARK bookm;

	if (offset)
	{
		if (is->fseek(offset, SEEK_SET)) goto error;
	} else
	{
		reset();
		return false;
	}
	// read "HISTORY" string
	char save_id[HISTORY_ID_LEN];
	if ((int)is->fread(save_id, HISTORY_ID_LEN) < HISTORY_ID_LEN) goto error;
	if (!strcmp(historySkipSaveID, save_id))
	{
		// string says to skip loading History
		FCEU_printf("No History in the file\n");
		reset();
		return false;
	}
	if (strcmp(historySaveID, save_id)) goto error;		// string is not valid
	// delete old items
	snapshots.resize(historySize);
	bookmarkBackups.resize(historySize);
	currentBranchNumberBackups.resize(historySize);
	// read vars
	if (!read32le(&historyCursorPos, is)) goto error;
	if (!read32le(&historyTotalItems, is)) goto error;
	if (historyCursorPos > historyTotalItems) goto error;
	historyStartPos = 0;
	// read items
	int total = historyTotalItems;
	if (historyTotalItems > historySize)
	{
		// user can't afford that much undo levels, skip some items
		int num_items_to_skip = historyTotalItems - historySize;
		// first try to skip items over history_cursor_pos (future items), because "redo" is less important than "undo"
		int num_redo_items = historyTotalItems-1 - historyCursorPos;
		if (num_items_to_skip >= num_redo_items)
		{
			// skip all redo items
			historyTotalItems = historyCursorPos+1;
			num_items_to_skip -= num_redo_items;
			// and still need to skip some undo items
			for (i = 0; i < num_items_to_skip; ++i)
			{
				if (snap.skipLoad(is)) goto error;
				if (bookm.skipLoad(is)) goto error;
				if (is->fseek(1, SEEK_CUR)) goto error;		// backup_current_branch
			}
			total -= num_items_to_skip;
			historyCursorPos -= num_items_to_skip;
		}
		historyTotalItems -= num_items_to_skip;
	}
	// load items
	for (i = 0; i < historyTotalItems; ++i)
	{
		if (snapshots[i].load(is)) goto error;
		if (bookmarkBackups[i].load(is)) goto error;
		if (is->fread(&currentBranchNumberBackups[i], 1) != 1) goto error;
		playback.setProgressbar(i, historyTotalItems);
	}
	// skip redo items if needed
	for (; i < total; ++i)
	{
		if (snap.skipLoad(is)) goto error;
		if (bookm.skipLoad(is)) goto error;
		if (is->fseek(1, SEEK_CUR)) goto error;		// backup_current_branch
	}

	// everything went well
	// init vars
	undoHintPos = oldUndoHintPos = undoHintTimer = -1;
	oldShowUndoHint = showUndoHint = false;
	updateList();
	redrawList();
	return false;
error:
	FCEU_printf("Error loading History\n");
	reset();
	return true;
}
示例#4
0
void GREENZONE::save(EMUFILE *os, int save_type)
{
	if (save_type != GREENZONE_SAVING_MODE_NO)
	{
		collectCurrentState();		// in case the project is being saved before the greenzone.update() was called within current frame
		runGreenzoneCleaning();
		if (greenzoneSize > (int)savestates.size())
			greenzoneSize = savestates.size();
		// write "GREENZONE" string
		os->fwrite(greenzone_save_id, GREENZONE_ID_LEN);
		// write LagLog
		lagLog.save(os);
		// write size
		write32le(greenzoneSize, os);
		// write Playback cursor position
		write32le(currFrameCounter, os);
	}
	int frame, size;
	int last_tick = 0;

	switch (save_type)
	{
		case GREENZONE_SAVING_MODE_ALL:
		{
			// write savestates
			for (frame = 0; frame < greenzoneSize; ++frame)
			{
				// update TASEditor progressbar from time to time
				if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
				{
					playback.setProgressbar(frame, greenzoneSize);
					last_tick = frame / PROGRESSBAR_UPDATE_RATE;
				}
				if (!savestates[frame].size()) continue;
				write32le(frame, os);
				// write savestate
				size = savestates[frame].size();
				write32le(size, os);
				os->fwrite(&savestates[frame][0], size);
			}
			// write -1 as eof for greenzone
			write32le(-1, os);
			break;
		}
		case GREENZONE_SAVING_MODE_16TH:
		{
			// write savestates
			for (frame = 0; frame < greenzoneSize; ++frame)
			{
				if (!(frame & 0xF) || frame == currFrameCounter)
				{
					// update TASEditor progressbar from time to time
					if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
					{
						playback.setProgressbar(frame, greenzoneSize);
						last_tick = frame / PROGRESSBAR_UPDATE_RATE;
					}
					if (!savestates[frame].size()) continue;
					write32le(frame, os);
					// write savestate
					size = savestates[frame].size();
					write32le(size, os);
					os->fwrite(&savestates[frame][0], size);
				}
			}
			// write -1 as eof for greenzone
			write32le(-1, os);
			break;
		}
		case GREENZONE_SAVING_MODE_MARKED:
		{
			// write savestates
			for (frame = 0; frame < greenzoneSize; ++frame)
			{
				if (markersManager.getMarkerAtFrame(frame) || frame == currFrameCounter)
				{
					// update TASEditor progressbar from time to time
					if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
					{
						playback.setProgressbar(frame, greenzoneSize);
						last_tick = frame / PROGRESSBAR_UPDATE_RATE;
					}
					if (!savestates[frame].size()) continue;
					write32le(frame, os);
					// write savestate
					size = savestates[frame].size();
					write32le(size, os);
					os->fwrite(&savestates[frame][0], size);
				}
			}
			// write -1 as eof for greenzone
			write32le(-1, os);
			break;
		}
		case GREENZONE_SAVING_MODE_NO:
		{
			// write "GREENZONX" string
			os->fwrite(greenzone_skipsave_id, GREENZONE_ID_LEN);
			// write LagLog
			lagLog.save(os);
			// write Playback cursor position
			write32le(currFrameCounter, os);
			if (currFrameCounter > 0)
			{
				// write ONE savestate for currFrameCounter
				collectCurrentState();
				int size = savestates[currFrameCounter].size();
				write32le(size, os);
				os->fwrite(&savestates[currFrameCounter][0], size);
			}
			break;
		}
	}
}