ZMV Editor (experts!)

General area for talk about ZSNES. The best place to ask for related questions as well as troubleshooting.

Moderator: ZSNES Mods

blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

ZMV Editor (experts!)

Post by blackdrake »

Hello.

I have a big ZMV file that shows the completing of a game from the very beginning. I want to edit this ZMV file to make it working with the German version of the ROM (message boxes are often longer than in the English version -> player has to press the A-button more often to close the text windows).

Therefore, I have to insert key sequenzes in the middle of the ZMV file at specific positions. As far as I know, ZSNES doesn't support inserting an sequence (would this be a good improvement suggestion)?

Do you know how I can edit a ZMV file? Are there ZMV editors or converters for ZMV<->SMV or ZMV<->PlainText? I also would use Hexeditors, but this is very complex.

I know the structure of a ZMV file ( http://tasvideos.org/ZMV.html ), but I think that this doesn't fit to my ZMV file because it seems to be an old file format. My ZMV file begins with "ZSNES Save State File V0.6".

I am very experienced with computers and I even am able to program something. That means, if I exactly know the structure of my ZMV file, I could write a program that translates the file into readable code. But it seems to be complex to realize that a specific sequence (wait x Frames, then press "A") is inserted in the middle of the ZMV...

Can anybody help me?

Regards
blackdrake
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

Well, if you can program something, then you should be able to follow this.

There's a ZST with a 16 byte header at the beginning, everything after that is input data.

Code: Select all

struct
{
  FILE *fp;
  size_t frames_replayed;
  struct
  {
    uint32_t A;
    uint32_t B;
    uint32_t C;
    uint32_t D;
    uint32_t E;
  } last_joy_state;
} old_movie;

static void OldMovieReplay()
{
  uint8_t byte;

  if (fread(&byte, 1, 1, old_movie.fp))
  {
    if (byte < 2) // 1 or 0 are correct values
    {
      char *sub;

      if (byte == 0) // 0 means the input has changed
      {
        fread(&old_movie.last_joy_state.A, 1, 4, old_movie.fp);
        fread(&old_movie.last_joy_state.B, 1, 4, old_movie.fp);
        fread(&old_movie.last_joy_state.C, 1, 4, old_movie.fp);
        fread(&old_movie.last_joy_state.D, 1, 4, old_movie.fp);
        fread(&old_movie.last_joy_state.E, 1, 4, old_movie.fp);
      }

      JoyAOrig = old_movie.last_joy_state.A;
      JoyBOrig = old_movie.last_joy_state.B;
      JoyCOrig = old_movie.last_joy_state.C;
      JoyDOrig = old_movie.last_joy_state.D;
      JoyEOrig = old_movie.last_joy_state.E;
Should be quite obvious how it works.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Hello.

Thank you for your answer.

Alas, I can not really understand how it works. I also do not understand C++ (I am programming in Delphi). But your code is just a fragment.

I am wondering how the OLD zmv file format works.

I found out following:
- I have a header with the title "ZSNES Save State File V0.6".
- At the beginning there is probably a simple save state.
- At Offset $43290 I have a 21 byte sequence which repeats. (00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) I think that's the stream part. But how is it working in the old file format? I think the informations seen at http://tasvideos.org/ZMV.html doesn't fit.

Can you help me with this?

Best regards
Daniel Marschall
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

Rough translation:

Code: Select all

Type    tLastJoyState   =       packed Record
                                A               :       DWord;
                                B               :       DWord;
                                C               :       DWord;
                                D               :       DWord;
                                E               :       DWord;
                                End;


        tOldMovie       =       Record
                                fp              :       tFileStream;
                                frames_replayed :       size_t;
                                last_joy_state  :       tLastJoyState;
                                End;


Var     old_movie       :       tOldMovie;


Procedure OldMovieReplay;
Var     _byte           :       Byte;
        sub             :       ^Char;
Begin
With old_movie do
If (fp.Read(_byte, 1) = 1) then Begin
        With last_joy_state do
        If (_byte < 2) then Begin               // 1 or 0 are correct values
                If (_byte = 0) then Begin       // 0 means the input has changed
                        fp.Read(A, 4);
                        fp.Read(B, 4);
                        fp.Read(C, 4);
                        fp.Read(D, 4);
                        fp.Read(E, 4);
                End;
                JoyAOrig = A;
                JoyBOrig = B;
                JoyCOrig = C;
                JoyDOrig = D;
                JoyEOrig = E;
...
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
Neo Kaiser
Veteran
Posts: 844
Joined: Thu Jul 29, 2004 3:56 am

Post by Neo Kaiser »

blackdrake wrote:Hello.

Thank you for your answer.

Alas, I can not really understand how it works. I also do not understand C++ (I am programming in Delphi). But your code is just a fragment.

I am wondering how the OLD zmv file format works.

I found out following:
- I have a header with the title "ZSNES Save State File V0.6".
- At the beginning there is probably a simple save state.
- At Offset $43290 I have a 21 byte sequence which repeats. (00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) I think that's the stream part. But how is it working in the old file format? I think the informations seen at http://tasvideos.org/ZMV.html doesn't fit.

Can you help me with this?

Best regards
Daniel Marschall
Delphi? you mean Pascal? That's surely is a very obsolete language.

EDIT: Ignore this post as I was unaware that Delphi is now a complete suit
with other languages than Pascal. Excuse my ignorance...
Yes I know that my grammar sucks!
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Hello.

Thank you for your answer. In my opinion, Delphi/Pascal is a good language, but that's not the point. I am able to understand your code. But it doesn't help me.

My ZMV file is a bit weird. As I descriped, I have a 21 byte sequence that is probably the streaming part. But what does these 21 bytes mean? I could not find any resources that explain the file structure of the old ZMV's.

And what do you mean with "Joystates" in your code?

I need an explination that says me, byte #1 is for buttom "A" or something. I also do not understand why the 2nd or 3rd byte has the value $80.

PS: Do you know any ZMV converter that converts the old format in the new one? Maybe I can work with it better. If you know any editors, converters or other ZMV tools, please let me know.

Best regards
Daniel Marschall
Last edited by blackdrake on Fri Apr 04, 2008 1:29 pm, edited 1 time in total.
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

"Joystate" probably means joypad state (status).

Neo Kaiser:
Object Pascal is very different from the original Pascal... has been for ages since Turbo Pascal (the
inofficial standard in DOS times) came out. Today, Free Pascal is also quite good, although less known.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

creaothceann wrote:"Joystate" probably means joypad state (status).
Yes, that's clear. But I have to know how the "joypad state" exactly works, so that I can analyze the bytes correctly.
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

00 means frame changed, so read 20 bytes of input data.
01 means frame didn't change, don't read anything for this frame, reuse last frame data.

There's 5 controllers, each one uses 4 bytes for input data. Each bit represents a different button.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Hello.

Thank you for information. I started to create a program to read out the ZMV. But I have a few problems.

As far as I understood, the first byte of the sequence $80 (Bits: 1000 0000) means: Controller 1 changed. Because this video only uses 1 controller, I will ignore the other cases.

The next 4 bytes show a 4 Byte DWord value for the controler 1 change event, right?

That means, my sequence has ALWAYS following structure:

Code: Select all

   A           B           C           D           E
80 xx xx xx xx 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
And now? What content do the DWord A have????

I found out that there are at least following values:

0, 128, 512, 1536, 2048, 16384, 16896, 17408 ... and many other possibilities

Can you please tell me how the DWord A has to be handled? What do I have to check, so that I get e.g. the result "A-Byte ... means: Button A, X and Down-Button pressed in this frame".

Edit: I saw in http://tasvideos.org/ZMV.html that there are 12 bits used for controller pressed keys. Please tell me what bit stand for which key!

Thank you.

Best regards
Daniel Marschall
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

... time to pull the blunt truth, since noone did it yet:

Guesses:
- you're probably talking about SD3.
- you're probably working on Saturn's run.
- you probably like entertaining SNES games.

Facts:
- RPGs such as SD3 often use a PRNG for a lot of stuff. Adding any different keypresses, any delay, even a single frame of different or delayed input will impact the PRNG, be it 100 or 32454657 frames from the modification point.
- Saturn made that video on ZSNES v0.990 or 0.989, iirc.

Mostly unbiased opinions:
- That run completely blows except for the following points.
- Fast forward through it all until you get to the black rabite fight.
- Laugh as Saturn fails to get a treasure chest from it.
- Repeatedly.
- Seriously, that run sucks. If you ever played the game, you probably did better.

Consequences:
- Fact 1 makes your idea impossible. And I don't mean Saturn-grade impossible, even though he made the movie.
- Fact 2 forces you to use the same version of ZSNES or else the movie will desync by itself. Modifying it with the German, turn-into-PAL-timing patch will not really help.
- Fact 2 also indicates that the game is played by a conceited fool. But that one might not matter to you.
- You probably won't enjoy it even in German. I'm a decently hardcore fan of the game and found watching the 2-days-long movie boring to all hell (except for opinion #3, of course).

Summary:
- Your idea won't work.
- Ever.
- Stop while you're ahead and save yourself from hours of coding, debugging, and the frustration that would ensue as you watch the movie desync under 100 seconds.

Thanks for listening, good night.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Hello.

Thank you for your answer. This comment confuses me a lot. Well, yes I am talking about a ZMV of Saturn. But I do not talk about SD3. I am talking of Terranigma. The ZMV was made for the English version. In the German version there are sometimes longer message boxes, so I have to add sequences to it. At my point of view there should be no problems, because I just add some additional frames. The game is the very same. Are you really sure that it won't work? If it just means a lot of work, I have no problem with that. Anyway, I will try to modify the ZMV to see if the first message-box with 3 instead of 2 text-windows works. If not, I have the answer.

Best regards
Daniel Marschall
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

blackdrake wrote:This comment confuses me a lot. Well, yes I am talking about a ZMV of Saturn. But I do not talk about SD3. I am talking of Terranigma.
Hmm, I failed at guessing the game. Still got much to learn from Nach.
... don't worry about being confused. ^^;

This is what will change for the better:
- The game is already PAL, so no added timing issue from the patch itself.
- Much better movie.

This is what won't change for the worse:
- It will still get different random numbers due to more keypresses/different delays, which will ultimately cause desyncs.
At my point of view there should be no problems, because I just add some additional frames. The game is the very same. Are you really sure that it won't work?
Yes, it's the same game (well, I think it is - the random code could be different in each ROM, but that's kind of unlikely).
However, the same game with different input will yield different result.
"Just adding" a couple frames is enough for enemy behaviour to change - that's what TASers call luck manipulation and intentionally exploit.
For a simple example, if the random generator updates its seed every X milliseconds, adding delays will make things change.
Or, if the code counts how many keys are pressed to update the seed, more presses will also cause differences.
Of course it could do both (and worse).
If it just means a lot of work, I have no problem with that.
Well, there's an alternative... make a movie yourself :). It's a lot of work, but it -will- work eventually.
Anyway, I will try to modify the ZMV to see if the first message-box with 3 instead of 2 text-windows works. If not, I have the answer.
The message boxes probably won't desync - they aren't relying on random. You want to test if monsters have the same behaviour or else Ark will not hit them/get hit by them.
You can try this:
Edit the english movie so that it waits for some seconds before pressing the button at one of the first textboxes. And watch the resulting movie with the english rom.
If it doesn't desync at all, then you can try your project. :)
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Hello.

I haven't thought about the random generator. This might cause a problem. I will try to edit the movie and look if a desync happens. Thank you for this information.

Best regards
Daniel Marschall
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Alas, it probably won't work. I added a long pause in one of the first dialogs and in the first tower a desync happend (probably because of a changed enemy behavior). It's a pity, Saturns movies are so great, and I wanted to have a German Terranigma video... :(
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

As already mentionned, you can do your own. :)

Also I'm kinda relieved you realised that it wouldn't work early enough.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
whicker
Trooper
Posts: 479
Joined: Sat Nov 27, 2004 4:33 am

Post by whicker »

grinvader wrote:As already mentionned, you can do your own. :)

Also I'm kinda relieved you realised that it wouldn't work early enough.
only thanks to grinvader's lengthy explanation, however.
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Hello.

I have found out, that the random-generator isn't depended on the keys pressed. I inserted 5000 key presses without frame increasing and there was no desync.

The movie by Saturn is so excellent, it is a masterwork. I cannot beat that. So I don't want to play the game myself for movie recording.

I could "translate" the ZMV by inserting the dialog-terminating keypresses. I also now understand the whole (old) ZMV file format and I created a ZMV-editor (will be released as OpenSource when it is done).

But I have 1 problem remaining that it neccessary for my "project":

The ZMV do desync at the newer ZSNesW versions. It only works synchron at ZSNes 0.96 and ZSNesW 1.00. The major problem is: I need a frame counter that shows me the actual frame, so that I can determinate the position of dialogs, that have changed in the German version of the game. And I didn't found a frame counter in ZSNesW 1.000. Did I oversee the function? How can I get this information? Or is there a trick, so that the newer ZSNesW works synchron with the old ZMVs?

Best regards
blackdrake
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

There is no trick. Core modifications cause desyncs.
And there is no frame counter in those old versions.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

My modifications without inserting or deleting frames do not cause desyncs. My project would work, because my changes do not change the random generator of the ROM.

But I need a correct frame counter. If I knew the current FPS, I could determinate the current frame.

The problem with the newer ZSNesW is, that it cannot play old ZMV correctly. It causes desync (also with the original ZMV). The ZMV only works with ZSNesW 0.96 and 1.000. But I think that this problem is known and unsolvable. :(
Deathlike2
ZSNES Developer
ZSNES Developer
Posts: 6747
Joined: Tue Dec 28, 2004 6:47 am

Post by Deathlike2 »

What grinvader is saying is that the core modifications between the two different versions of ZSNES are causing the dsyncs, regardless of the new/old movie format changes/differences.
Continuing [url=http://slickproductions.org/forum/index.php?board=13.0]FF4[/url] Research...
blackdrake
Rookie
Posts: 11
Joined: Thu Apr 03, 2008 7:33 pm
Location: Germany

Post by blackdrake »

Sorry, I misunderstood it. It's a pity that old ZMVs can't be played correctly. I don't understood it at all. I read something that the newer ZSNesW need more CPU time and this causes desync.

ZSNesW is OpenSource, isn't it? Is it possible to edit version 1.000 for adding the frame counter? Or is the source inaccessable because of the old version?
Deathlike2
ZSNES Developer
ZSNES Developer
Posts: 6747
Joined: Tue Dec 28, 2004 6:47 am

Post by Deathlike2 »

ZSNES was open sourced way past v1.00 (since 1.20, which is accessible), so there's nothing that can be referenced from to make changes with.
Continuing [url=http://slickproductions.org/forum/index.php?board=13.0]FF4[/url] Research...
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

blackdrake wrote:I read something that the newer ZSNesW need more CPU time and this causes desync.
Nothing to do with CPU requirements. Emulation accuracy is improved over time, which means that the game code is emulated (slightly) differently.

For example, a game might finish a loop faster/slower and expect the next key status earlier/later. ZMVs update the key status on a frame-by-frame basis. With a different ZSNES version, the timing might shift by one or more frames, and the ZMVs provide the right input at the wrong time.

Normal speedruns might not desync if you're lucky, but for TASes optimized down to single frames it's deadly.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
Saturn
New Member
Posts: 7
Joined: Sat Jul 16, 2005 6:26 pm
Contact:

Post by Saturn »

Dear Mr. "know-it-all" grinvader,

Although it's a bit late, I wanted to let you know that I'm glad you enjoyed my SD3 run in full detail, but if you don't mind, allow me to correct a few things I thought were obvious, but apparently aren't to some people:
grinvader wrote: Mostly unbiased opinions:
- Seriously, that run sucks. If you ever played the game, you probably did better.
That's true that I was a bit over-careful in some critical situations, but just to remind you, the run was played in a single-segment, so I didn't want to take the risk getting killed at the near end of the movie and thus waste all the time and effort I spent on it so far. You are invited to try beating SD3 in a single-segment as well (with just the possibility to pause the recording via "ESC"), then maybe you would be able to understand how much experience and skill it would require to beat this game in this conditions.
grinvader wrote:Consequences:
- Fact 2 ("Saturn made that video on ZSNES v0.990 or 0.989, iirc") also indicates that the game is played by a conceited fool. But that one might not matter to you.
Hint: Try to read the readme.txt that was included in the zip with the movie to understand why I used the older version of ZSNES. If it's too hard, here again: I used v989c because all newer versions of ZSNES "desynced" after a short while and therefore would make a single-segmented movie recording of that length impossible in any way (which I thought a ZSNES developer should know best). I just had no other choice at that time.
grinvader wrote: - You probably won't enjoy it even in German. I'm a decently hardcore fan of the game and found watching the 2-days-long movie boring to all hell (except for opinion #3, of course).
If you are able to read, then you would see that the last save right before heading to the final boss was done at around 15 hours (with max a half hour more spent until the very end of the movie). If you equate 15 hours to a span of 2 days, then maybe you should refresh your knowledge about time-units one more time.


And blackdrake, as other have already said, it's unfortunately impossible to edit any zmvs without causing desyncs due to their RNG. And it's also impossible to playback this older 0.989c movies on any of the newer windows versions of ZSNES, so there is just no other way than to watch them on the version they were recorded.

And in case you are interested in the Terranigma run, I did a improved version of it, which is only available on my site in the ZSNES section, because Zophar stopped accepting new zmvs since the beginning of 2004. It's even available as a AVI file on archive.org (all links available on my site). Enjoy the movies!
See my perfect 100% movie walkthroughs of the best RPG games on http://www.freewebs.com/saturnsmovies/index.htm
Various TASes and Speed Trick videos of popular games: http://www.youtube.com/user/SaturnTAS
Post Reply