byuu wrote:Only because you asked for feedback ...
I did, and it is always appreciated. You thought of some things which I hadn't, which is a good thing
. I do have some responses though.
> and can be located anywhere within the file
What if two tags appear in the same file? Some emulators will invariably go with the first, others with the last, regardless of what you say in the specification.
That would have to be addressed on a spec level. First matched tag seems reasonable to me as it would be the easiest for an author to implement. Also, it's what other similar specifications have done (multiboot, ACPI tables, etc) with much success.
With any spec, there is a reasonable expectation and requirement for people to follow it for it to be useful. While it is true that some people will of course not follow it correctly. I could say the same thing about any spec
, even iNES 1.0 and 2.0. People could easily choose to interpret some bits the wrong way and not play the game correctly.
There is a silver lining though, most (if not all) NES emulator authors are members of this forum, so it is at least possible to get the majority of emulators on board with doing it right, which is enough for it to work.
> I would enforce that it must be on a 4-byte boundary so make the search efficient.
Other emulators would happily ignore this, and then homebrew makers would ignore it, and then you'd look like the broken implementation for enforcing this rule.
Good point, I would have hoped that anyone trying this spec out would do it right, but definitely some people would not. Fortunately, that is nothing more than an optimization which could be dropped. Any alignment would work, just doing it by uint32_t's make it 4 times faster to locate it.
> 100% backwards compatible, should not break old emulators
You have to insert the data somewhere into existing ROMs. If you put it at the end, you will most certainly break some emulators that rely on file sizes instead of header info. Eg one might say "read iNES PRG ROM size, and assume CHR ROM size == remaining file size."
Interesting point. I know that GoodNES hashing everything after the first 16 bytes, so it would be effected (that's how it determines overdumps). It's a problem, but, I don't think it's a major problem, here's why:
#1 it is no different as far as these emulators are concerned from an overdump, there is just some extra data at the end.
#2 emulators which ignore the iNES headers and use hashes instead are fairly new and likely still in development to some degree, so we could work with the authors to get it right.
#3 truly legacy emulators (i mean the ones from the 90's) definitely rely on the iNES 1.0 header, so they won't be effected.
#4 every emulator which makes decisions based on hashes would be insane not to fall back on iNES headers if there isn't a match found. That's what would happen here. It's not perfect, but most games are playable under those conditions.
#5 taking into consideration point #4, those same emulators would have to continually update there database of checksums to keep up with new releases or they risk not being able to play new dumps/home brews. If they are keeping up, they can either add these new "overdumps", or update there emulator to handle it more gracefully.
#6 regarding "read iNES PRG ROM size, and assume CHR ROM size == remaining file size.", that's interesting, and certainly someone
has done it. But the resultant CHR ROM size wouldn't be a valid size (not a multiple of 8192). So they would pretty much have to truncate it since they would not have a whole page at the end.
#7 I have a (admitadly stalled) "Open GoodNES" project which aims to be an open source / open DB alternative GoodNES. This may be a good reason to resume work on it!
> easy to apply to existing ROMs, you just append it to the ROM file.
Breaks checksums of files, breaks existing emulator CRC32 lookups.
This is pretty much the same as the previous point.
> versioned, so we can add new fields as the community strives for more and more accurate emulation.
Versioning creates as many problems as it solves. But for something like this, I don't see much choice. Especially when everyone keeps insisting on non-extensible data formats.
Agreed, I think it's necessary, but can be done carefully to make it easy to get right.
> because it can be located anywhere, it's size is not limited. So if a new version wants to add some new bytes to the structure, it's trivial to do so.
The header should just specify the packet size.
Agreed! Now that I think of it, it should be done similar to Microsoft APIs. Size is
the version. The structure should have a size field instead of a version field. And you simply never remove fields, only append to the end (potentially deprecating previous ones). This has worked for almost 30 years and if there is one thing they succeed at, it's maintaining compatibility with older versions of there API.
All in all, you make some good critiques, but I don't think any of them would be deal breakers. The need is not to get every
emulator to do it right, but only the most popular ones. The rest will follow suite if that happens.