Custom OP Movie Insertion

#1

This tutorial is to insert custom video as game opening movie, not to port or edit the vanilla one.
In fact, the vanilla opening animation is not a video but procs, so it has nothing to do with the custom one here. It is similar to custom spell animation at this point. How to disable the vanilla opening.

Convert video format

Convert video with any video editor you like. I use free software Format Factory.


Output video information:

Complete name                            : F:\FFOutput\»ìÁ÷190707183637.mp4
Format                                   : MPEG-4
Format profile                           : Base Media
Codec ID                                 : isom (isom)
File size                                : 2.89 MiB
Duration                                 : 2 min 32 s
Overall bit rate mode                    : Variable
Overall bit rate                         : 160 kb/s
Encoded date                             : UTC 2019-07-07 11:01:45
Tagged date                              : UTC 2019-07-07 11:01:45
Writing application                      : FormatFactory

Video
ID                                       : 1
Format                                   : MPEG-4 Visual
Format profile                           : Simple@L1
Format settings, BVOP                    : No
Format settings, QPel                    : No
Format settings, GMC                     : No warppoints
Format settings, Matrix                  : Default (H.263)
Codec ID                                 : mp4v-20
Duration                                 : 2 min 32 s
Bit rate mode                            : Variable
Bit rate                                 : 61.8 kb/s
Maximum bit rate                         : 380 kb/s
Width                                    : 240 pixels
Height                                   : 160 pixels
Display aspect ratio                     : 3:2
Frame rate mode                          : Constant
Frame rate                               : 8.000 FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Compression mode                         : Lossy
Bits/(Pixel*Frame)                       : 0.201
Stream size                              : 1.12 MiB (39%)
Writing library                          : Lavc58.18.100
Tagged date                              : UTC 2019-07-07 11:01:46

Audio
ID                                       : 2
Format                                   : AAC
Format/Info                              : Advanced Audio Codec
Format profile                           : LC
Codec ID                                 : mp4a-40-2
Duration                                 : 2 min 32 s
Bit rate mode                            : Variable
Bit rate                                 : 96.0 kb/s
Maximum bit rate                         : 133 kb/s
Channel(s)                               : 2 channels
Channel positions                        : Front: L R
Sampling rate                            : 22.05 kHz
Frame rate                               : 21.533 FPS (1024 SPF)
Compression mode                         : Lossy
Stream size                              : 1.75 MiB (61%)
Encoded date                             : UTC 2019-07-07 11:01:45
Tagged date                              : UTC 2019-07-07 11:01:46

Notice that the configuration parameters are not fixed. Try to balance size and quality by yourself.
Then convert it to AVI format.

Format                                   : AVI
Format/Info                              : Audio Video Interleave
File size                                : 3.03 MiB
Duration                                 : 2 min 32 s
Overall bit rate                         : 167 kb/s
Writing application                      : Lavf58.12.100

Video
ID                                       : 0
Format                                   : MPEG-4 Visual
Format profile                           : Simple@L1
Format settings, BVOP                    : No
Format settings, QPel                    : No
Format settings, GMC                     : No warppoints
Format settings, Matrix                  : Default (H.263)
Codec ID                                 : FMP4
Duration                                 : 2 min 32 s
Bit rate                                 : 61.6 kb/s
Width                                    : 240 pixels
Height                                   : 160 pixels
Display aspect ratio                     : 3:2
Frame rate                               : 8.000 FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Compression mode                         : Lossy
Bits/(Pixel*Frame)                       : 0.200
Stream size                              : 1.12 MiB (37%)
Writing library                          : Lavc58.18.100

Audio
ID                                       : 1
Format                                   : MPEG Audio
Format version                           : Version 2
Format profile                           : Layer 3
Format settings                          : Joint stereo / MS Stereo
Codec ID                                 : 55
Codec ID/Hint                            : MP3
Duration                                 : 2 min 32 s
Bit rate mode                            : Constant
Bit rate                                 : 96.0 kb/s
Channel(s)                               : 2 channels
Sampling rate                            : 22.05 kHz
Compression mode                         : Lossy
Stream size                              : 1.74 MiB (57%)
Alignment                                : Aligned on interleaves
Interleave, duration                     : 26  ms (0.21 video frame)
Interleave, preload duration             : 52  ms
Writing library                          : LAME3.99.5

Notice that the configuration parameters are not fixed. Try to balance size and quality by yourself.

Link to the ROM

Encapsulate the video to a GBA ROM with Meteo. It is a very old commercial softeware and its website is dead now. Google to find a copy of it.


Notice that the configuration parameters are not fixed. Try to balance size and quality by yourself.
Then you can use gbafix to fix the ROM header, but it is not necessary, so I omit it here.
At last, add it to the end of the game ROM.
copy /b game.gba+FEESOVOP2.gba game_FEESOVOP2.gba

Fix pointers

Find all pointers in FEESOVOP2.gba and fix them by adding an offset (the size of game.gba) in game_FEESOVOP2.gba.
That is the hardest part and I use IDA to assist my analysis. In fact, it works even if some pointers are missed, and all ROMs generated by Meteo have the similar structure, so don’t be afraid.
Here is the pointer list I found:

8009C2C 80001BD 80002D8 800030C 8009CFC 857B3EC

Notice that they are not fixed. Try to find and confirm them by yourself. I cannot ensure that mine is compete, so feel free to add it if you find a new pointer.
Then patch this:

80000C0: (whatever) -> FE FF 3F EA
9000000: 2E 00 00 EA -> 78 47 00 00 (whatever at 80000C0) 2D 00 C0 EA

Search 01 21 38 1C and jump to the first (its address should be bigger than 9000000), change FA E7 (4 bytes after 01 21 38 1C) to FC E6.

Test

Test on GBA emulator: https://youtu.be/E4a2HsJq3Ro
Test on GBA machine: https://youtu.be/7jEqIFWxPAg
Patches are in Unified Dropbox.

12 Likes
#2

wow this is awesome. Great work!

1 Like
#3

This is amazing. Just wondering, would it be possible to write an asm routine that plays a cut scene during a chapter event?

2 Likes
#4

I guess it is possible as long as you allocate enough space for the video player in WRAM.