Unsure how to make VMU saves

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
User avatar
Protofall
DCEmu Crazy Poster
DCEmu Crazy Poster
Posts: 26
Joined: Sun Jan 14, 2018 8:03 pm
Location: Emu land
Contact:

Unsure how to make VMU saves

Post by Protofall » Tue Nov 27, 2018 6:07 am

I've checked some old forum posts for advice on how to create/save/load save files and every example I see is basically a modified version of the save/load functions from WolfDC (Indiket's version is a little more clear <viewtopic.php?f=34&t=103666&p=1047688&h ... e#p1047688>).

I'm starting with basics and trying to make a "create" savefile function without zlib compression (That will be easy to add later).
//insert the includes here

typedef struct SaveFile{
	uint32_t var1;
	uint8_t var2;
} SaveFile_t;

SaveFile_t save;
unsigned char * icon;	//uint8_t
unsigned short * palette;	//uint16_t

int DC_CreateVMUSaveFile(char *src){
	char dst[32];

	vmu_pkg_t pkg;
	uint8_t *pkg_out;
	int pkg_size;

	//Setup the save file ready to go into a VMU header
	uint8_t * data;
	int filesize = sizeof(SaveFile_t);
	data = (uint8_t *) malloc(filesize);
	memcpy(data, &save, filesize);

	// Our VMU + full save name
	strcpy(dst, "/vmu/a1/");
	strcat(dst, src);

	// Required VMU header
	strcpy(pkg.desc_short, "Crayon\\DC");	//I think the \\DC is redundant
	strcpy(pkg.desc_long, "Game Save");
	strcpy(pkg.app_id, "CRAYON_VMU_TEST\\DC");

	memcpy(&pkg.icon_pal[0], palette, 32);
	pkg.icon_data = icon;
	pkg.data_len = filesize;
	pkg.data = data;
	vmu_pkg_build(&pkg, &pkg_out, &pkg_size);

	pkg.icon_cnt = 1;
	pkg.icon_anim_speed = 0;
	pkg.eyecatch_type = VMUPKG_EC_NONE;

	// Save the newly created VMU save to the VMU
	file_t file = fs_open(dst, O_WRONLY);		//Errors
	if(file == -1){
		printf("File DNE\n");
	}
	printf("%d\n", file);
	fs_write(file, pkg_out, pkg_size);
	fs_close(file);							//Errors

	// Free unused memory
	free(pkg_out);
	free(data);
	return 0;
}

// Romdisk
extern uint8 romdisk_boot[];
KOS_INIT_ROMDISK(romdisk_boot);

int main(void){
	pvr_init_defaults();

	save.var1 = 20000;
	save.var2 = 41;

	file_t file;
	file = fs_open("/rd/IMAGE.BIN", O_RDONLY);
	int filesize = fs_total(file);
	icon = (unsigned char *) malloc(filesize);
	fs_read(file, icon, filesize);
	fs_close(file);

	file = fs_open("/rd/PALLETTE.BIN", O_RDONLY);
	int filesize2 = fs_total(file);
	palette = (unsigned short *) malloc(filesize2);
	fs_read(file, palette, filesize2);
	fs_close(file);

	DC_CreateVMUSaveFile("hii");

	// main loop goes here

	return 0;
}
This code will only attempt to save to VMU a1. It also makes the assumption that VMU a1 is present and has enough space for the save file. Currently this is fine, although I'll want to fix that later. I'm also using lxdream for testing since I don't want to try on real hardware and accidentally brick my VMU. According to some of the posts I read, lxdream should be able to handle this.

When I run this code I get two read errors on the lines with the "Errors" comments on them (As is it continues on, but if I add some printf's for the file descriptors when loading IMAGE.BIN and PALLETTE.BIN then it crashes after the second "Errors" read fails...weird).

I think the main problem is that I'm trying to open a file that doesn't exist yet, being "/vmu/a1/hii" (I'm not even sure if that's a valid name or if it needs to have a certain extension) and I don't see a function that makes a new file in the VFS (Aside from `fs_load()` which I don't think I want for this). The docs for `fs_open()` don't mention whether its supposed to return -1 if the file DNE or it makes a new empty file. It doesn't even make sense for `fs_open()` to make a new file because it wouldn't know how large you want it to be. The file descriptor when printed is 3, not -1 so I don't know what to make of this.
Working on a recreation of Minesweeper for the Dreamcast <viewtopic.php?f=34&t=104820>

Twitter <https://twitter.com/ProfessorToffal>
YouTube (Not much there, but there are a few things) <https://www.youtube.com/user/TrueMenfa>
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5365
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Contact:

Re: Unsure how to make VMU saves

Post by BlueCrab » Tue Nov 27, 2018 7:27 am

First off, moved to the right forum. ;-)

Second, when you call fs_open() with a mode of O_WRONLY, it will create a new file if the file doesn't exist -- just like doing an 'fopen(filename, "wb");' would (which also brings up the point that you can just use the normal fopen(), fread(), and fwrite() functions just as well as the fs_ versions for doing your VMU saves, if you want). Also, in the case of VMU stuff, the file created is just in memory, until you close the file -- the code doesn't need to know how big the file is in either case though just to create it. Other than the VMU not being existent/connected/formatted, I can't think of a good reason for it to fail on the creation of the file. If it is indeed failing there, I'd suspect you have something wrong in your lxdream setup, or it doesn't actually support what you're trying to do.

You don't have to worry about bricking a VMU -- the only thing you might need to worry about (if you really manage to hose something bad) is the VMU needing to be reformatted -- but that should be sufficiently difficult to make happen.

Also, since you haven't found many good examples of how to do things, here's how I did it in my SMS emulator: https://sourceforge.net/p/crabemu/code/ ... mem.c#l832 . My version there does take care of making sure that there's actually a VMU attached and that it has enough space, so that might be helpful to you, at least (also, it does do compression with zlib too).
User avatar
Protofall
DCEmu Crazy Poster
DCEmu Crazy Poster
Posts: 26
Joined: Sun Jan 14, 2018 8:03 pm
Location: Emu land
Contact:

Re: Unsure how to make VMU saves

Post by Protofall » Tue Nov 27, 2018 7:46 am

BlueCrab wrote:
Tue Nov 27, 2018 7:27 am
First off, moved to the right forum. ;-)

Second, when you call fs_open() with a mode of O_WRONLY, it will create a new file if the file doesn't exist -- just like doing an 'fopen(filename, "wb");' would (which also brings up the point that you can just use the normal fopen(), fread(), and fwrite() functions just as well as the fs_ versions for doing your VMU saves, if you want). Also, in the case of VMU stuff, the file created is just in memory, until you close the file -- the code doesn't need to know how big the file is in either case though just to create it. Other than the VMU not being existent/connected/formatted, I can't think of a good reason for it to fail on the creation of the file. If it is indeed failing there, I'd suspect you have something wrong in your lxdream setup, or it doesn't actually support what you're trying to do.

You don't have to worry about bricking a VMU -- the only thing you might need to worry about (if you really manage to hose something bad) is the VMU needing to be reformatted -- but that should be sufficiently difficult to make happen.

Also, since you haven't found many good examples of how to do things, here's how I did it in my SMS emulator: https://sourceforge.net/p/crabemu/code/ ... mem.c#l832 . My version there does take care of making sure that there's actually a VMU attached and that it has enough space, so that might be helpful to you, at least (also, it does do compression with zlib too).
Whoops, I meant to post in homebrew. Don't know how my post ended up here :o :oops:

The exact error lxdream gave me was:
vmu_block_read failed: DATATRF(8)/02000000
vmufs_root_read: can't read block 255 on device A1
VMUFS: unable to realloc another 512 bytes
vmu_block_read failed: DATATRF(8)/02000000
vmufs_root_read: can't read block 255 on device A1
I thought I set up my VMU right, I can view it normally in the BIOS and all. Maybe there was an extra setup step I missed.

I'll run the code I have on hardware with an empty VMU out of curiosity, but that link you provided should be really useful/much better than what I have. :grin:
Working on a recreation of Minesweeper for the Dreamcast <viewtopic.php?f=34&t=104820>

Twitter <https://twitter.com/ProfessorToffal>
YouTube (Not much there, but there are a few things) <https://www.youtube.com/user/TrueMenfa>
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5365
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Contact:

Re: Unsure how to make VMU saves

Post by BlueCrab » Tue Nov 27, 2018 7:49 am

Your post ended up in the Programming forum because I moved it here. It belongs here, not in the top forum, as it is a programming related question. ;-)

The errors you've posted there imply that whatever lxdream is doing with the VMU isn't working, as KOS cannot read it. Those should not happen on real hardware.
User avatar
Protofall
DCEmu Crazy Poster
DCEmu Crazy Poster
Posts: 26
Joined: Sun Jan 14, 2018 8:03 pm
Location: Emu land
Contact:

Re: Unsure how to make VMU saves

Post by Protofall » Tue Nov 27, 2018 8:49 am

BlueCrab wrote:
Tue Nov 27, 2018 7:49 am
Your post ended up in the Programming forum because I moved it here. It belongs here, not in the top forum, as it is a programming related question. ;-)

The errors you've posted there imply that whatever lxdream is doing with the VMU isn't working, as KOS cannot read it. Those should not happen on real hardware.
Top forum? Even weirder, maybe I pressed create a new post on the wrong page by mistake :?

I've just ran this in the redream emulator. It doesn't give errors and does make a file. However that file's icon is a red X in a circle with a yellow background, most of the descriptions are missing (With exception of "hii", the filename) and the file is only 1 block long (I expected the save icon stuff + save data to be 2 blocks since the icon + palette is more than 1 block) I'm not too surprised on the block count and icon since its probably just not including the icon in the file, but the missing descriptions and possibly other vars is strange...I'll try out your code tomorrow

Image
Working on a recreation of Minesweeper for the Dreamcast <viewtopic.php?f=34&t=104820>

Twitter <https://twitter.com/ProfessorToffal>
YouTube (Not much there, but there are a few things) <https://www.youtube.com/user/TrueMenfa>
Post Reply