Homebrew Video Cutscenes

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
Of course we all want to have video cutscenes in our games. It makes them more professional looking. But, has anyone managed to do it with an AVI file just yet? I'm curious to know this because I was doing a bit of research into that last night (At 2 AM to boot) and I found an interesting piece of homebrew. Well, two of them, but they both revolve around the same idea. First, to see what I am getting at, visit this page and download either the nyands or rickroll nds files and watch them. Yes, I'm serious. Watch them. The reason for that is the way they create a video effect is shown in the source (Which is also provided on that page!) and how well it works. The only downside to their app is the .nds file is very large. But, how they did it was displaying a bunch of .raw image files at a fast enough of a speed to emulate a video, then played the audio alongside it to simulate a video effect.

Is there a better alternative, because I'd like to make a video cutscene (The video I want to use is 50 seconds long and has 755 frames- that'd make a huge NDS file!) but I'd rather make the task simple and not have to use frame-by-frame image playback as it'd be inefficient to use. Or is a video library for devkitpro in development?
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
so its plays video`s directly from the nds rom?
It's not a video. It's a large sequence of raw images that play in a way that represents a video. In the 30 second Rickroll video, there is 330 frames to make the video. Watch the NDS images in NO$GBA, Desmume seems to not like them.
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
The best solution is to use a collection of jpg images, rather than raw images. this solution is similar to the mjpeg video codec.
I'm curious to see code for this. The only issue I'd have now is making it load. I'd need to decide on FAT access or embedding it in the ROM. And since I'm only starting to learn, this will be a lot of fun.

But hey - We all start somewhere!
 

Dirbaio

Well-Known Member
Member
Joined
Sep 26, 2010
Messages
158
Trophies
0
Age
111
Location
Spain
Website
dirbaio.net
XP
108
Country
You can take a look at what I coded for Fireworlds.
It plays a video format I made myself, that features a really simple compression scheme. The compression ratio is not good (I'd say 3-4 times smaller than just storing the raw 16bpp 256x192 frames) but on the other hand it's efficient enough to play back at 30fps. It could get even more efficient if it was coded in ASM, though getting to 60fps is impossible. Videos in Fireworlds are 20fps though.
Also, the VRAM is double-buffered so there's no tearing.

http://code.google.com/p/fireworlds/source/browse/trunk/fireworlds-game/arm9/source/video.itcm.cpp

There's also the encoder for the format, here. Made in java, it's REALLY slow.

http://code.google.com/p/fireworlds/source/browse/#svn%2Ftrunk%2Fvds-encoder
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
You can take a look at what I coded for Fireworlds.
It plays a video format I made myself, that features a really simple compression scheme. The compression ratio is not good (I'd say 3-4 times smaller than just storing the raw 16bpp 256x192 frames) but on the other hand it's efficient enough to play back at 30fps. It could get even more efficient if it was coded in ASM, though getting to 60fps is impossible. Videos in Fireworlds are 20fps though.
Also, the VRAM is double-buffered so there's no tearing.

http://code.google.c.../video.itcm.cpp

There's also the encoder for the format, here. Made in java, it's REALLY slow.

http://code.google.c...k%2Fvds-encoder
This looks good. I'll look and see what I can do with it and I'll also have to figure out how to add it. Plus, I averaged the video to approximately 15 FPS, so it should play at near-full speed!

...I hate having to learn this.
 

Dirbaio

Well-Known Member
Member
Joined
Sep 26, 2010
Messages
158
Trophies
0
Age
111
Location
Spain
Website
dirbaio.net
XP
108
Country
Nice :)

If you have any questions about it, just ask me and I'll see what I can do!

You'll probably need it with the video encoder, it's in a really primitive state :(
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
Nice :)

If you have any questions about it, just ask me and I'll see what I can do!

You'll probably need it with the video encoder, it's in a really primitive state :(
Yeah. I try to convert stuff and only get a 1 byte-sized file. I'm guessing that it's looking for the sequences of .jpg files? Or does it want the .avi?

Edit: Got it. Now it's doing stuff. Now if I could find some way to quickly load it so I can see how fast it plays.

Edit 2: To make it really quick, I copied it to Fireworlds and loaded it because I don't want to have to type out the code to play it. But, the video conversion is really nice! The only issue I have is that it plays too fast, about 20 seconds too fast.The video in it's avi form is, as stated, 50 seconds. The .vds is 30 seconds. I'm guessing though, that you can change that when you add the ability to play video in the source code, how fast it plays (FPS)?

Edit 3: I did some math and it seems that your videos play at 25 FPS and mine plays at 15. I would assume there is a parameter for that, though?
 

Dirbaio

Well-Known Member
Member
Joined
Sep 26, 2010
Messages
158
Trophies
0
Age
111
Location
Spain
Website
dirbaio.net
XP
108
Country
Yes, it's in video.itcm.cpp, line 87. Change that 20 to whatever you want, it's in frames per second.

Also, in case you want to put the video decoder in your own project, this is the only code you need. (besides initializing FAT, of course)
main.itcm.cpp line 347
http://code.google.com/p/fireworlds/source/browse/trunk/fireworlds-game/arm9/source/main.itcm.cpp#347
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
Yes, it's in video.itcm.cpp, line 87. Change that 20 to whatever you want, it's in frames per second.

Also, in case you want to put the video decoder in your own project, this is the only code you need. (besides initializing FAT, of course)
main.itcm.cpp line 347
http://code.google.c...in.itcm.cpp#347
I will definitely use it. It looks really good and it will work for what I need it. Thank you so much.

I might have some more questions as I'm still playing with the code and getting it to work, like button presses and whatnot so it'll be touch and go from here on.
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
Well, once I get my button presses figured out, I'll have to see how you call the video up. First, I need to get to that point. And I'm already having issues. I guess I'll have to keep trying until I get an expected result.
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
Ok yeah. I can't get button presses working. At all.

Code:
-------------------------------------------------

NightFox's Lib Template
Ejemplo carga de fondos en 16bits (modo BITMAP)

Requiere DevkitARM
Requiere NightFox's Lib

Codigo por NightFox
http://www.nightfoxandco.com
Inicio 10 de Octubre del 2009

(c)2009 - 2011 NightFox & Co.

-------------------------------------------------
-------------------------------------------------
Includes
-------------------------------------------------
*/

// Includes C
#include 
#include 
#include 

// Includes propietarios NDS
#include 

// Includes librerias propias
#include 

/*
-------------------------------------------------
Main() - Bloque general del programa (Mod by TF)
-------------------------------------------------
*/

int main(int argc, char **argv) {

// Pantalla de espera inicializando NitroFS
NF_Set2D(0, 0);
NF_Set2D(1, 0);
consoleDemoInit();
iprintf("Initiating FAT... Please Wait.\n\nIf you are stuck here, try\nrestarting your DS.\n\nIf that does not fix\nthe issue, try \nre-patching DLDI if your\ncard doesn't support\nit.");
int count = 300;
while(count--) swiWaitForVBlank;
u16 keys = 0;

// Define el ROOT e inicializa el sistema de archivos
NF_SetRootFolder("Crazy_Moto"); // Define la carpeta ROOT para usar NITROFS

// Inicializa el motor 2D en modo BITMAP
NF_Set2D(0, 5); // Modo 2D_5 en ambas pantallas
NF_Set2D(1, 5);

// Inicializa los fondos en modo "BITMAP"
NF_InitBitmapBgSys(0, 1);
NF_InitBitmapBgSys(1, 1);
consoleClear(); //Clears text console.

// Inicializa los buffers para guardar fondos en formato BITMAP
NF_Init16bitsBgBuffers();

// Carga el archivo BITMAP de imagen en formato RAW a la RAM
NF_Load16bitsBg("bmp/top_intro_1", 0);
NF_Load16bitsBg("bmp/touch_intro_1", 1);
// Tranfiere la imagen a la VRAM de ambas pantallas
NF_Copy16bitsBuffer(0, 0, 0);
NF_Copy16bitsBuffer(1, 0, 1);
iprintf("Nothing else to see.");

// Si no es necesario usarla mas, borrala de la RAM
NF_Unload16bitsBg(0);
NF_Unload16bitsBg(1);

while(1) {
scanKeys();
if(!(keysHeld() & KEY_A)) {
NF_Load16bitsBg("bmp/top_intro_2", 0);
NF_Load16bitsBg("bmp/touch_intro_2", 1);
NF_Copy16bitsBuffer(0, 0, 0);
NF_Copy16bitsBuffer(1, 0, 1);
NF_Unload16bitsBg(0);
NF_Unload16bitsBg(1);
while (1) {
swiWaitForVBlank();
if (!(keysHeld() & KEY_A)) systemShutDown();
}
}
else (swiWaitForVBlank());
}

return 0;

}
I'm building off NightFox's 16bgbitsload example, but I can't get button A to unload top/touch_intro_1 and load top/touch_intro_2 to the screen. All this does is display an image for a split second before shutting off. Once I can get that to work, then I'll figure out where to put the video code, but I want to sort this out first. What in the world am I doing wrong?
 

LeRodeur

Well-Known Member
Member
Joined
Dec 12, 2009
Messages
162
Trophies
0
Age
30
XP
190
Country
France
I dont really know nflib but.. With your code if A isn't pressed it loads the bg, unloads it and automatically power off because you have the same condition for the shutdown.. Plus I don't really understand what you want to do
edit: plus when program reaches the second while, keys are not refreshed in the loop anymore and the else swiwait is useless (will be called two times so your fps will drop to 30)
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
I dont really know nflib but.. With your code if A isn't pressed it loads the bg, unloads it and automatically power off because you have the same condition for the shutdown.. Plus I don't really understand what you want to do
edit: plus when program reaches the second while, keys are not refreshed in the loop anymore and the else swiwait is useless (will be called two times so your fps will drop to 30)
Well, I should have mentioned that. *headdesk*

I need it to display top/touch_intro_1 and wait for button A before unloading it and loading top/touch_intro_2. Once that has happened, I want A to shut off the DS until I can get more code in there to program the cutscene and see how this lib works.
 

LeRodeur

Well-Known Member
Member
Joined
Dec 12, 2009
Messages
162
Trophies
0
Age
30
XP
190
Country
France
Then you should do this

load the first bg;
while( !(keysHeld() & KEY_A)) { scanKeys();}
Load second;
scankeys();
while( !(keysnewpress() & KEY_A)) { scanKeys();}
Unload second;
shutdown;
 

loco365

Well-Known Member
OP
Member
Joined
Sep 1, 2010
Messages
5,457
Trophies
0
XP
2,927
Then you should do this

load the first bg;
while( !(keysHeld() & KEY_A)) { scanKeys();}
Load second;
scankeys();
while( !(keysnewpress() & KEY_A)) { scanKeys();}
Unload second;
shutdown;

Ok. So I now have this:
Code:
// Carga el archivo BITMAP de imagen en formato RAW a la RAM
NF_Load16bitsBg("bmp/top_intro_1", 0);
NF_Load16bitsBg("bmp/touch_intro_1", 1);
// Tranfiere la imagen a la VRAM de ambas pantallas
NF_Copy16bitsBuffer(0, 0, 0);
NF_Copy16bitsBuffer(1, 0, 1);

// Si no es necesario usarla mas, borrala de la RAM
while( !(keysHeld() & KEY_A)) { scanKeys();}
NF_Unload16bitsBg(0);
NF_Unload16bitsBg(1);
NF_Reset16bitsBgBuffers(); //This just resets the buffers and clears out RAM for the next image.
NF_Load16bitsBg("bmp/top_intro_2", 0);
NF_Load16bitsBg("bmp/touch_intro_2", 1);
NF_Copy16bitsBuffer(0, 0, 0);
NF_Copy16bitsBuffer(1, 0, 1);
while( !(keysHeld() & KEY_A)) { scanKeys();}
NF_Unload16bitsBg(0);
NF_Unload16bitsBg(1);
NF_Reset16bitsBgBuffers();
systemShutDown();
Pressing A just shuts it off. Here is the makefile process:
Code:
main.c
arm-eabi-gcc -MMD -MP -MF /c/devkitPro/examples/graphics/bg16bitsload/build/main
.d -g -Wall -O2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math
-mthumb -mthumb-interwork -iquote /c/devkitPro/examples/graphics/bg16bitsload/i
nclude -I/c/devkitPro/libnds/include -I/c/devkitPro/examples/graphics/bg16bitslo
ad/nflib/include -I/c/devkitPro/examples/graphics/bg16bitsload/build -DARM9 -c /
c/devkitPro/examples/graphics/bg16bitsload/source/main.c -o main.o
c:/devkitPro/examples/graphics/bg16bitsload/source/main.c: In function 'main':
c:/devkitPro/examples/graphics/bg16bitsload/source/main.c:47:17: warning: statem
ent with no effect [-Wunused-value]
c:/devkitPro/examples/graphics/bg16bitsload/source/main.c:48:6: warning: unused
variable 'keys' [-Wunused-variable]
linking bg16bitsload.elf
Nintendo DS rom tool 1.50 - Oct 15 2011
by Rafael Vuijk, Dave Murphy, Alexei Karpenko
built ... bg16bitsload.nds
Press any key to continue . . .
 

Dirbaio

Well-Known Member
Member
Joined
Sep 26, 2010
Messages
158
Trophies
0
Age
111
Location
Spain
Website
dirbaio.net
XP
108
Country
Oh, I think I know what's going on :)

The DS waits in the first loop for A to be pressed. When you press it, it loads the other BG and proceeds to do the second loop. BUT when it arrives there the button A is still pressed (the DS loads the BG faster than you can press and release the button). Then it doesn't even wait for another button press, and proceeds to shut down :)

To fix it you could use keysDown() instead of keysHeld():

keysHeld returns true when the button is pressed, but keysDown only returns true if the button was just pressed since the last key read.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    NinStar @ NinStar: :whip: