예제 #1
0
static void replace_click(GtkWidget* widget, gpointer data) {
	GtkTreeIter iter;
	stateheader* sh;
	if (_filePath != NULL && gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), NULL, &iter)) {
		gtk_tree_model_get(GTK_TREE_MODEL(listStore), &iter, 1, &sh, -1);

		GtkWidget* dialog = gtk_file_chooser_dialog_new("Replace", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
		gint res = gtk_dialog_run(GTK_DIALOG(dialog));
		if (res != GTK_RESPONSE_ACCEPT) {
			gtk_widget_destroy(dialog);
			return;
		}

		char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
		FILE* f = fopen(path, "rb");
		gtk_widget_destroy(dialog);

		fseek(f, 0, SEEK_END);
		size_t len = ftell(f);
		if (len > 65536) len = 65536; // prevent using too much memory on opening big file by accident
		char* gbc_data = (char*)malloc(len);
		fseek(f, 0, SEEK_SET);
		size_t total_bytes_read = 0;
		while (total_bytes_read < len) {
			size_t bytes_read = fread(gbc_data, 1, len - total_bytes_read, f);
			total_bytes_read += bytes_read;
			if (bytes_read <= 0) {
				error_msg("Could only read %lu bytes from %s", (unsigned long)total_bytes_read, path); 
				free(gbc_data);
				g_free(path);
				fclose(f);
				return;
			}
		}

		g_free(path);
		fclose(f);

		// only first X bytes will be used, where X is uncompressed size of current data
		void* new_data = goomba_new_sav(loaded_file, sh, gbc_data, len);
		free(gbc_data);
		if (new_data == NULL) {
			error_msg("%s", goomba_last_error());
		} else {
			memcpy(loaded_file, new_data, GOOMBA_COLOR_SRAM_SIZE);
			dirty = true;
			free(new_data);

			header_scan();
		}
	}
}
예제 #2
0
bool SaveBatteryOrState(char * filepath, int action, bool silent)
{
	bool result = false;
	int offset = 0;
	int datasize = 0; // we need the actual size of the data written
	int device;
	
	if(!FindDevice(filepath, &device))
		return 0;

	if(action == FILE_SNAPSHOT && gameScreenPngSize > 0)
	{
		char screenpath[1024];
		strncpy(screenpath, filepath, 1024);
		screenpath[strlen(screenpath)-4] = 0;
		sprintf(screenpath, "%s.png", screenpath);
		SaveFile((char *)gameScreenPng, screenpath, gameScreenPngSize, silent);
	}

	AllocSaveBuffer();

	// put VBA memory into savebuffer, sets datasize to size of memory written
	if(action == FILE_SRAM)
	{
		if(cartridgeType == 1)
			datasize = MemgbWriteBatteryFile((char *)savebuffer);
		else
			datasize = MemCPUWriteBatteryFile((char *)savebuffer);
		
		if (cartridgeType == 1) {
			const char* generic_goomba_error = "Cannot save SRAM in Goomba format (did not load correctly.)";
			// check for goomba sram format
			char* old_sram = (char*)malloc(GOOMBA_COLOR_SRAM_SIZE);
			size_t br = LoadFile(old_sram, filepath, GOOMBA_COLOR_SRAM_SIZE, true);
			if (br >= GOOMBA_COLOR_SRAM_SIZE && goomba_is_sram(old_sram)) {
				void* cleaned = goomba_cleanup(old_sram);
				if (cleaned == NULL) {
					ErrorPrompt(generic_goomba_error);
					datasize = 0;
				} else {
					if (cleaned != old_sram) {
						free(old_sram);
						old_sram = (char*)cleaned;
					}
					stateheader* sh = stateheader_for(old_sram, RomTitle);
					if (sh == NULL) {
						// Game probably doesn't use SRAM
						datasize = 0;
					} else {
						void* new_sram = goomba_new_sav(old_sram, sh, savebuffer, datasize);
						if (new_sram == NULL) {
							ErrorPrompt(goomba_last_error());
							datasize = 0;
						} else {
							memcpy(savebuffer, new_sram, GOOMBA_COLOR_SRAM_SIZE);
							datasize = GOOMBA_COLOR_SRAM_SIZE;
							free(new_sram);
						}
					}
				}
			}
			free(old_sram);
		}
	}
	else
	{
		if(emulator.emuWriteMemState((char *)savebuffer, SAVEBUFFERSIZE))
			datasize = *((int *)(savebuffer+4)) + 8;
	}

	// write savebuffer into file
	if(datasize > 0)
	{
		offset = SaveFile(filepath, datasize, silent);

		if(offset > 0)
		{
			if(!silent)
				InfoPrompt ("Save successful");
			result = true;
		}
	}
	else
	{
		if(!silent)
			InfoPrompt("No data to save!");
	}

	FreeSaveBuffer();

	return result;
}
예제 #3
0
파일: fceuram.cpp 프로젝트: dborth/fceugx
bool SaveRAM (char * filepath, bool silent)
{
	bool retval = false;
	int datasize = 0;
	int offset = 0;
	int device;
			
	if(!FindDevice(filepath, &device))
		return 0;

	if(GameInfo->type == GIT_FDS)
	{
		if(!silent)
			InfoPrompt("RAM saving is not available for FDS games!");
		return false;
	}

	AllocSaveBuffer ();

	// save game save to savebuffer
	if(GameInfo->type == GIT_CART)
		datasize = WiiFCEU_GameSave(&iNESCart, 0);
	else if(GameInfo->type == GIT_VSUNI)
		datasize = WiiFCEU_GameSave(&UNIFCart, 0);

	if (datasize)
	{
		// Check to see if this is a PocketNES save file
		FILE* file = fopen(filepath, "rb");
		if (file)
		{
			uint32 tag;
			fread(&tag, sizeof(uint32), 1, file);
			fclose(file);
			
			if (goomba_is_sram(&tag))
			{
				void* gba_data = malloc(GOOMBA_COLOR_SRAM_SIZE);
				
				file = fopen(filepath, "rb");
				fread(gba_data, 1, GOOMBA_COLOR_SRAM_SIZE, file);
				fclose(file);
				
				void* cleaned = goomba_cleanup(gba_data);
				if (!cleaned) {
					ErrorPrompt(goomba_last_error());
				} else if (cleaned != gba_data) {
					memcpy(gba_data, cleaned, GOOMBA_COLOR_SRAM_SIZE);
					free(cleaned);
				}

				// Look for just one save file. If there aren't any, or there is more than one, don't read any data.
				const stateheader* sh1 = NULL;
				const stateheader* sh2 = NULL;

				const stateheader* sh = stateheader_first(gba_data);
				while (sh && stateheader_plausible(sh)) {
					if (little_endian_conv_16(sh->type) != GOOMBA_SRAMSAVE) {}
					else if (sh1 == NULL) {
						sh1 = sh;
					}
					else {
						sh2 = sh;
						break;
					}
					sh = stateheader_advance(sh);
				}

				if (sh1 == NULL)
				{
					ErrorPrompt("PocketNES save file has no SRAM.");
					datasize = 0;
				}
				else if (sh2 != NULL)
				{
					ErrorPrompt("PocketNES save file has more than one SRAM.");
					datasize = 0;
				}
				else
				{
					char* newdata = goomba_new_sav(gba_data, sh1, savebuffer, datasize);
					if (!newdata) {
						ErrorPrompt(goomba_last_error());
						datasize = 0;
					} else {
						memcpy(savebuffer, newdata, GOOMBA_COLOR_SRAM_SIZE);
						datasize = GOOMBA_COLOR_SRAM_SIZE;
						free(newdata);
					}
				}
			}
		}
	}

	if (datasize)
	{
		offset = SaveFile(filepath, datasize, silent);

		if (offset > 0)
		{
			if (!silent)
				InfoPrompt("Save successful");
			retval = true;
		}
	}
	else
	{
		if (!silent)
			InfoPrompt("No data to save!");
	}
	FreeSaveBuffer ();
	return retval;
}