SWBF mvs files discussion

Started by BAD_AL, June 17, 2020, 01:52:06 PM

Previous topic - Next topic
Will do;

Do you think the source movies were all in .bik format and then converted to .mvs with MovieMunge.exe?
I've not tried movieMunge.exe yet, but I'm curious if it does the work of converting .bik to .mvs.
I don't think the console input video lists are present in the mod tools, so I'm not sure what the input file types were for Xbox.
But looking at Shell/munge.bat (SWBF2):
for %%A in (%MUNGE_ROOT_DIR%\%SOURCE_SUBDIR%\%MUNGE_PLATFORM%\*.mlst) do moviemunge -input %%A -output %MUNGE_ROOT_DIR%\_LVL_%MUNGE_PLATFORM%\Movies\%%~nA.mvs -checkdate 2>>%MUNGE_LOG%


That "-output ...mvs" argument makes me think that all we may need is the .bik files for the input and the .mvs would be created for us.

Quote from: Dark_Phantom on June 17, 2020, 11:59:41 AM
https://github.com/phantom567459/SoundFMVextractor/releases/tag/1.1
Release thread here: http://www.swbfgamers.com/index.php?topic=13685.msg122784#msg122784

It's a command line program, make sure to read the readme.  It's not hard to use, but it works best when the videos you have and the program are in the same folder.

Beware, Xbox (xmv) video files (on either version) don't extract correctly, for whatever reason that I have not ascertained.  However, I don't think there's anything different about them other than a lower than PC quality and if there is, the PS2 version would have it (which there's a whole bunch of steps to get from point a to b.  It's been on my fix list for months and have gotten no further.

Well... I build the exe from latest source, used the tool to extract some videos, ftp'd them over to my Xbox and they seemed to play ok.
Looking at a binary diff of an extracted xmv video and a .mvs file, the extracted video seemed like it was correct.
The videos seemed off center on my monitor during playback, but the other .xmv videos (from other games) on the HDD that I tried seemed to behave the same way.

How sure are you that it doesn't work right?

June 17, 2020, 05:27:48 PM #2 Last Edit: June 17, 2020, 05:33:01 PM by Dark_Phantom
They SHOULD work right (like all the other files), however, something about them doesn't play in VLC media player correctly (even though I have other XMV files that work fine, so I assumed they were bad in some way).  (They would stop after like 3 seconds and glitch out)

I can cross that off the list if they work right.  VLC lied to me :)
The BOBclan:  A Rich History


Quote from: Unit 33 on November 29, 2014, 03:44:44 AM
'Please, tell me more about the logistics of the design of laser swords being wielded by space wizards' - Some guy on the internet.

When playing one of those movies I see code lik:
ScriptCB_OpenMovie("<movie>.mvs", "")

Each of those .mvs files is composed of several other movie files.
I've only seen the function calls specify the .mvs file (with "" as the 2nd argument), can you use the 2nd argument of 'ScriptCB_OpenMovie()' to specify a file within the .mvs file?

I think you have to play the movie like this:
ifelem_shellscreen_fnStartMovie(this.curItem.movie, 0, nil, nil, movie_left, movie_top, movie_width, movie_height)

I don't have any reference for the second parameter at this time.
The BOBclan:  A Rich History


Quote from: Unit 33 on November 29, 2014, 03:44:44 AM
'Please, tell me more about the logistics of the design of laser swords being wielded by space wizards' - Some guy on the internet.

Quote from: Dark_Phantom on June 17, 2020, 07:07:54 PM
I think you have to play the movie like this:
ifelem_shellscreen_fnStartMovie(this.curItem.movie, 0, nil, nil, movie_left, movie_top, movie_width, movie_height)

I don't have any reference for the second parameter at this time.

Ok...
So the 'ScriptCB_OpenMovie("<movie>.mvs", "")' opens the .mvs file for reading (callers set 'gMovieStream' to the result of this function) and the 'ifelem_shellscreen_fnStartMovie' (or ScriptCB_PlayMovie()) selects an element from the .mvs file to play (with movie name, loop, position, and size arguments).

The .mlst file goes into the munged '.mvs ' file, the .mcfg file is munged into another .lvl file, but I don't see any mapping lookup to get to the right segment of the .mvs file when a movie is played.

I'm not seeing how the name lookup works since the Lua files have the strings in them and the .mvs files don't seem to.

June 18, 2020, 10:37:27 AM #6 Last Edit: June 18, 2020, 10:42:01 AM by Dark_Phantom
Okay, I split this over to the modding board.  I'll start from the beginning for the benefit of the group even though you've already got a grasp of it.

For the 3 platforms, the files must be in the appropriate format BEFORE munge:

  • PC - .bik (using RAD game tools)
  • PS2 - .pss (using PSS Plex)
  • Xbox - .xmv (using Any2XMV or another converter)
Munge will add these to a .mvs file provided you have a .mlst (movie list) file in the same folder (as the munge is currently written. The .mlst file is stored at the top of the .mvs file, but i don't even use the location that is stored for my program because it was easier to hunt down BIK extension.  I believe, but have not confirmed, that the video calling system is a little more rudimentary than the sound engine.  It might use a simpler library (or just a different hash, which is unlikely) system to compare against what the lua is calling, but I remember that I just was not seeing it (but it has to identify them somehow).  I can do more research but I will probably have to ask someone else to look at it.

SUPER IMPORTANT NOTE THAT HASN'T BEEN MENTIONED:
I have munged videos successfully on all 3 systems for BF1.  For Xbox ingame videos, at least for BF1 (BF2 it may be ok) if you have issues:
After munge, you MUST edit the resulting file.  I don't know whether it's a configuration thing or what, but instead of 08 in the table of contents before each file, you must change them to 00.  This will allow them to run on the Xbox - if this flag is not changed, the game will crash when loading one of these videos.  A diff from the stock mvs files as compared to a new munge will make this clear.
The BOBclan:  A Rich History


Quote from: Unit 33 on November 29, 2014, 03:44:44 AM
'Please, tell me more about the logistics of the design of laser swords being wielded by space wizards' - Some guy on the internet.

I think it's super cool that you put the hash pairs in those separate files!
I just figured out that the "BF2_Tools\ToolsFl\bin" folder contains a program called "Hash.exe", which gives the hash value for the supplied (string) argument.
So one could add some more known strings if needed. :D


June 19, 2020, 05:15:09 AM #8 Last Edit: June 23, 2020, 12:36:36 PM by Dark_Phantom
I felt it was quicker in the long run to do it that way.  Psych0fred (a developer of the game) was nice enough to run their HashDirectory program on his folders so that I had the names of all the files. I used Excel functions to trim everything down to only what I needed. The files that are generated with a hash name in my program either do not have a name in his folders or were renamed during munge in the .sfx or .stm files.

The cool thing is that the program can be used to reverse hash as well.  Now, you likely aren't going to get the same name unless you sit for a LONG time (8 characters is when it starts becoming ridiculous to wait, which makes sense because it's getting exponentially bigger).  What you can do, is if you are trying to recreate a stock file for the game (like common.bnk) but it can't find the name, you can run reverse hash to generate a name that will give it the same hash in the sound file.

Edit: there was also an idea that if people supplied the hash pairs to their files they could be extracted again with the same name, but I didn't know if that would catch on or not.  It was kind of an edge case, but I have definitely manually added names in the list that weren't generated the first time around.

EDIT 2:  @ BAD_AL i confirmed I was searching for the wrong bytes in .mvs files to compare against.  The hashes are definitely in there, and at the time I was too lazy to do anything with them. (Fun fact, it should only be a small code rewrite, I don't have to change the hash pairs file because it's correct.)
The BOBclan:  A Rich History


Quote from: Unit 33 on November 29, 2014, 03:44:44 AM
'Please, tell me more about the logistics of the design of laser swords being wielded by space wizards' - Some guy on the internet.

I've been messing around with swbf-unmunge and was able to make some fixes to the way it handles the config files (I've actually only tested it on shell.lvl though).
But I was able to extract the 'shell_movies.mcfg' file with the exception of 1 string; in this snipit:


MovieProperties()
{
Name("shell_main");
Inherit("screen_template");
Movie("shell");
0x4d5af670(1);
SegmentList()
{
Segment("shell_main1", 1, 0);
Segment("shell_main2", 1, 0);
}
}

I also changed the hash return value to hex so that it could more easily be compared to the output of 'Hash.exe' in the tools directory.
Any clue what that last property name could be (0x4d5af670)?

Here's the rest:
[spoiler]
MovieProperties()
{
Name("transition_template");
FadeInTime(0);
FadeOutTime(0.200000);
}

MovieProperties()
{
Name("screen_template");
FadeInTime(0.100000);
FadeOutTime(0.500000);
}

MovieProperties()
{
Name("flythrough_template");
FadeInTime(1);
FadeOutTime(1);
}

MovieProperties()
{
Name("shell_main");
Inherit("screen_template");
Movie("shell");
0x4d5af670(1);
SegmentList()
{
Segment("shell_main1", 1, 0);
Segment("shell_main2", 1, 0);
}
}

MovieProperties()
{
Name("shell_sub_left");
Inherit("screen_template");
Movie("shell");
SegmentList()
{
Segment("shell_subrep2", 1, 0);
Segment("shell_subrep1", 1, 0);
Segment("shell_subcis1", 1, 0);
Segment("shell_subcis2", 1, 0);
Segment("shell_subimp1", 1, 0);
Segment("shell_suball1", 1, 0);
Segment("shell_suball2", 1, 0);
Segment("shell_subimp2", 1, 0);
}

}

MovieProperties()
{
Name("cor1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("cor1tran1", 1, 0);
}

}

MovieProperties()
{
Name("dea1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("dea1tran1", 1, 0);
}

}

MovieProperties()
{
Name("fel1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("fel1tran1", 1, 0);
}

}

MovieProperties()
{
Name("hot1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("hot1tran1", 1, 0);
}

}

MovieProperties()
{
Name("kam1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("kam1tran1", 1, 0);
}

}

MovieProperties()
{
Name("kas2tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("kas2tran1", 1, 0);
}

}

MovieProperties()
{
Name("mus1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("mus1tran1", 1, 0);
}

}

MovieProperties()
{
Name("myg1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("myg1tran1", 1, 0);
}

}

MovieProperties()
{
Name("nab1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("nab1tran1", 1, 0);
}

}

MovieProperties()
{
Name("pol1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("pol1tran1", 1, 0);
}

}

MovieProperties()
{
Name("sb1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("sb1tran1", 1, 0);
}

}

MovieProperties()
{
Name("sb2tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("sb2tran1", 1, 0);
}

}

MovieProperties()
{
Name("sb3tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("sb3tran1", 1, 0);
}

}

MovieProperties()
{
Name("sb4tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("sb4tran1", 1, 0);
}

}

MovieProperties()
{
Name("tan1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("tan1tran1", 1, 0);
}

}

MovieProperties()
{
Name("uta1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("uta1tran1", 1, 0);
}

}

MovieProperties()
{
Name("yav1tran1");
Inherit("transition_template");
Movie("shell");
SegmentList()
{
Segment("yav1tran1", 1, 0);
}

}

MovieProperties()
{
Name("crawl1");
Inherit("screen_template");
Movie("shell");
SegmentList()
{
Segment("crawl1", 1, 0);
}

}

MovieProperties()
{
Name("crawl2");
Inherit("screen_template");
Movie("shell");
SegmentList()
{
Segment("crawl2", 1, 0);
}

}

MovieProperties()
{
Name("gcwinall1");
Inherit("transition_template");
Movie("shell");
FadeInTime(1);
FadeOutTime(1);
SegmentList()
{
Segment("gcwinall1", 1, 0);
}

}

MovieProperties()
{
Name("gcwincis1");
Inherit("transition_template");
Movie("shell");
FadeInTime(1);
FadeOutTime(1);
SegmentList()
{
Segment("gcwincis1", 1, 0);
}

}

MovieProperties()
{
Name("gcwinimp1");
Inherit("transition_template");
Movie("shell");
FadeInTime(1);
FadeOutTime(1);
SegmentList()
{
Segment("gcwinimp1", 1, 0);
}

}

MovieProperties()
{
Name("gcwinrep1");
Inherit("transition_template");
Movie("shell");
FadeInTime(1);
FadeOutTime(1);
SegmentList()
{
Segment("gcwinrep1", 1, 0);
}

}

MovieProperties()
{
Name("attractmovie");
Inherit("transition_template");
Movie("shell");
FadeInTime(1);
FadeOutTime(1);
0x4d5af670(1);
SegmentList()
{
Segment("attractcw1", 1, 0);
Segment("attractgcw1", 1, 0);
}

}

MovieProperties()
{
Name("training");
Inherit("screen_template");
Movie("shell");
SegmentList()
{
Segment("training1", 1, 0);
}
}


[/spoiler]

It's almost definitely CyclePlayback.  I'm not at my home PC or I would actually hash it so you know for sure.
The BOBclan:  A Rich History


Quote from: Unit 33 on November 29, 2014, 03:44:44 AM
'Please, tell me more about the logistics of the design of laser swords being wielded by space wizards' - Some guy on the internet.

Quote from: Dark_Phantom on June 25, 2020, 05:15:24 AM
It's almost definitely CyclePlayback.  I'm not at my home PC or I would actually hash it so you know for sure.
Yep, that's what it is!

I'll add that one to the dictionary.

Thanks Phantom  :D

Quote from: Dark_Phantom on June 19, 2020, 05:15:09 AM
I felt it was quicker in the long run to do it that way.  Psych0fred (a developer of the game) was nice enough to run their HashDirectory program on his folders so that I had the names of all the files. I used Excel functions to trim everything down to only what I needed. The files that are generated with a hash name in my program either do not have a name in his folders or were renamed during munge in the .sfx or .stm files.

The cool thing is that the program can be used to reverse hash as well.  Now, you likely aren't going to get the same name unless you sit for a LONG time (8 characters is when it starts becoming ridiculous to wait, which makes sense because it's getting exponentially bigger).  What you can do, is if you are trying to recreate a stock file for the game (like common.bnk) but it can't find the name, you can run reverse hash to generate a name that will give it the same hash in the sound file.

Edit: there was also an idea that if people supplied the hash pairs to their files they could be extracted again with the same name, but I didn't know if that would catch on or not.  It was kind of an edge case, but I have definitely manually added names in the list that weren't generated the first time around.

EDIT 2:  @ BAD_AL i confirmed I was searching for the wrong bytes in .mvs files to compare against.  The hashes are definitely in there, and at the time I was too lazy to do anything with them. (Fun fact, it should only be a small code rewrite, I don't have to change the hash pairs file because it's correct.)

Yes, looking at this last night I did fund the following hashes in the xbox shell.mvs file:

location:0x24; hash:0x11e1fc01: shell       
location:0x3c; hash:0xfe2fc846: shell_main1
location:0x5c; hash:0xfd2fc6b3: shell_main2
location:0x7c; hash:0x5c30920e: shell_suball1
location:0x9c; hash:0x5b30907b: shell_suball2
location:0xbc; hash:0x95c29a10: shell_subcis1
location:0xdc; hash:0x98c29ec9: shell_subcis2
location:0xfc; hash:0x2dce2e3d: shell_subimp1
location:0x11c; hash:0x2ace2984: shell_subimp2
location:0x13c; hash:0x92ef3a6: shell_subrep1
location:0x15c; hash:0x82ef213: shell_subrep2
location:0x17c; hash:0xbac76daa: cor1tran1
location:0x19c; hash:0xf1c1532c: dea1tran1
location:0x1bc; hash:0xc00a9f2d: fel1tran1
location:0x1dc; hash:0xee3ec9f9: hot1tran1
location:0x1fc; hash:0xafefaf99: kam1tran1
location:0x21c; hash:0x2950238: kas2tran1
location:0x23c; hash:0x4f3a1981: mus1tran1
location:0x25c; hash:0x55ab8611: myg1tran1
location:0x27c; hash:0x20579dcb: nab1tran1
location:0x29c; hash:0xd9503729: pol1tran1
location:0x2bc; hash:0x839573d5: sb1tran1
location:0x2dc; hash:0x36f9d9ce: sb2tran1
location:0x2fc; hash:0xe8b7dcc7: sb3tran1
location:0x31c; hash:0xa62393d8: sb4tran1
location:0x33c; hash:0xb7b223fd: tan1tran1
location:0x35c; hash:0x6d770b22: uta1tran1
location:0x37c; hash:0xeb3f9b96: yav1tran1
location:0x39c; hash:0xb4a21ed9: gcwinall1
location:0x3bc; hash:0x3d379d5f: gcwincis1
location:0x3dc; hash:0x3bc33baa: gcwinimp1
location:0x3fc; hash:0x72e4c431: gcwinrep1
location:0x41c; hash:0x601d5913: attractcw1
location:0x43c; hash:0xad7828b4: attractgcw1
location:0x45c; hash:0x9bb7a572: training1

That's one more hash than xmv file pulled out, so probably that the first hash is the title of the list, the rest are movie file names.