Jo Engine Forum

Sega Saturn Development => General Jo Engine Help => Topic started by: SaturnTeam on July 09, 2018, 09:02:04 pm

Title: How to autoload game after video
Post by: SaturnTeam on July 09, 2018, 09:02:04 pm
I'm not sure if this is straight forward or not. I'm trying to figure out if there needs to be a jump from one C file to the main or running a header file from the main file. Should the video C or header file be in a separate directory? Right now, I keep running out of memory due to all the assets being loaded at the same time. I want to run the video, clear that, and then load the game assets.
Title: Re: How to autoload game after video
Post by: ponut64 on July 10, 2018, 04:55:23 am
You should have a look at the jo_free command, since you're loading everything with Jo engine.
You should be able to use jo_free to free up the memory allocated by the video.
That said, I don't use jo engine loading features so I am not sure how it works.
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 10, 2018, 06:53:00 pm
Yeah, that seems to be what I'm missing. I'm using the suspend command to hold the game until the video plays, but I need the free command to clear the memory. I'm still trying to figure it out, but I haven't had much luck. I've been looking at addresses that get returned in debug in Yabause, but I'm not totally clear on how to set up the malloc and free commands in the code.

Johannes, can you explain how this is supposed to work? I've been reading up on how malloc normally works in C coding, but I keep getting address or file size errors.
Title: Re: How to autoload game after video
Post by: ponut64 on July 10, 2018, 10:03:37 pm
My guess looking at jo_free, whatever variable you are using to reference the data (like jo_get_video_sprite), you put that in jo_free.
Maybe the man himself will come and explain it for cinepaks.
Title: Re: How to autoload game after video
Post by: logi on July 11, 2018, 03:27:33 pm
I am experiencing the same issue.
This is not something that I particularly need to implement, but it would be nice to figure out how to properly clear the memory after a video has been loaded.

When the video sample application is running it is using 71% of dynamic memory and 32% of sprite memory, according to the returned values of jo_memory_usage_percent() and jo_sprite_usage_percent() respectively.

When the video stops playing and the my_video_stopped() callback function is executed, the jo_memory_usage_percent() returns a zero, indicating that the video data is no longer consuming the dynamic memory, but the jo_sprite_usage_percent() returns 32, showing that the data has not been cleared from the sprite memory.

When I call the jo_sprite_free_from() function passing it the jo_get_video_sprite() function for the sprite ID, this then clears the sprite memory, at which point both the jo_memory_usage_percent() and jo_sprite_usage_percent() return a zero.

If I then try to load the background image from the background sample (usually consumes 4% sprite memory) I receive an out of memory error message.
https://www.youtube.com/watch?v=OtGekEpw_ro (https://www.youtube.com/watch?v=OtGekEpw_ro)
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 11, 2018, 04:07:01 pm
Yeah. That's something I've come across while working on this. I think I'm getting close to solving it. I was making progress last night. I'm going to work on it today. If I don't get it working, I'll post the code that I'm using so I can get more eyeballs on the code. If I get it working, I'll post how I did it. One of the problems I've run across is that, compared to how it's noted in the source document, different coding sites give slightly different implementation examples. Some of the coding tutorials conform to C and others to C++.
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 11, 2018, 11:48:33 pm
Update: I think I have most of the right code, but I still can't figure it out.

EXECUTION CODE IN MAIN.C:
Code: [Select]
#include "video.h"

#define jo_extended_ram_cartridge_type(CART_32MBits)

void     jo_main(void)
{
    jo_core_init(JO_COLOR_Black);
    jo_core_suspend();
//    jo_malloc(sizeof(int));
    jo_core_add_callback(my_draw2);
    jo_core_add_callback(my_video_stopped);
    jo_core_add_callback(jo_main2);
if (jo_video_open_file("SAMPLE.CPK"))
        jo_video_play(my_video_stopped);
    jo_free((void*) video);
    jo_core_suspend();
...blablabla
}

HEADER FILE:
Code: [Select]
#ifndef __VIDEO_H__
# define __VIDEO_H__


#include <jo/jo.h>

#define jo_extended_ram_cartridge_type(CART_32MBits)

const int *video;

void     my_draw2(void)
{
    video = jo_video_open_file; //0x06024970 0x044   0x80   0x013  0x1F8
    const int *video = (const int*) jo_malloc(268000*sizeof(int));
    if(video == NULL)
    {
        jo_printf(1, 2, "Unable to allocate memory", jo_get_last_error());
//        jo_printf(0, 1, "Address of video variable: %d\n", *video);
//        return JO_NULL;
    }
    // Yes, it consume a lot of memory during playing :)
    jo_printf(0, 0, "Dynamic memory usage: %d%%  ", jo_memory_usage_percent());

    jo_sprite_draw3D(jo_get_video_sprite(), 0, 0, 170);
}

void                my_video_stopped(void)
{
    jo_printf(0, 1, "Done.");
}

void     jo_main2(void)
{
jo_core_init(JO_COLOR_Transparent);
jo_core_add_callback(my_draw2);
// if (jo_video_open_file("SAMPLE.CPK"))
//        jo_video_play(my_video_stopped);
jo_core_run();
}
#endif /* !__VIDEO_H__ */

/*
** END OF FILE
*/

Other than that, I added JO_COMPILE_WITH_RAM_CARD_SUPPORT to my makefile. I think I'll start working on a different approach. I think if I make it a separate video C file in a different folder, I might be able to get it to work. I'm just about done for today. I had to make one of the background colors transparent, because most of the time the error information was getting covered by black all over the screen. I am getting two errors: NULL pointer in jo_free, and GFS cannot determine file size.
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 12, 2018, 07:31:19 pm
My attempt to run it from another C file failed. Now, I've been trying to run everything from the main file. I keep getting the error: in_jo_fs_get_file_size(): GFS_Open() failed. I've tried setting a max malloc size in the makefile, enabling ram card support, and turning on sgl. Nothing works. I have no clue what to do. I have Yabuase set to use the 4MB ram cart. My game disc data is close to 4MB total.
Title: Re: How to autoload game after video
Post by: ponut64 on July 12, 2018, 08:50:29 pm
At this point, you're going to have to look over the SBL GFS documentation (and the way Jo engine loads the file) so you can make your own function to load the CPK without a malloc. By doing that, when Jo engine loads something else, it won't try to append it to the end of the allocated area.
Relatively simple, you just need to identify the struct that jo engine wants the CPK in and read up on how GFS_Load works.
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 15, 2018, 06:22:02 pm
I am still working on this. I have been reading through the engine code to see how the videos are loaded and played. Before, it was getting hung up on just finding the file and reading the size. Now, I have everything in one file and have moved most of the video code to the top of the file. Before, most of the code was mixed in lower parts of the file. In the demo, the video is loaded in jo_main with a function up above that signifies the stopping of the video. Of course, the demo is just running one asset, so there is no confusion. Now that I have moved the code into a new function at the top of the file, I am no longer getting the first errors in the error list the code is supposed to run through, which was finding the file and getting the size. It has moved down the list to the error for creating the video before it plays. I can get it to the point where I can see the multicolor lines on the screen where it is trying to play the video, but the game freezes underneath it.
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 16, 2018, 12:54:11 am
This is a very frustrating problem. I have gotten it to the point where it's starting to draw the lines for the video. It stops and says that the pointer in jo_free is bad and returns an address of 6070f90. As of now, I'm not calling jo_free, so this is the jo_free that is included in the video launching process in the video.c file. The video address, according to the video demo, is in the 6000000/0x60000 series. After that, it says "in __jo_cpk_error_handling(): Cinepak Error 0x101" followed by "CPK_CreateGfsMovie() failed".
Title: Re: How to autoload game after video
Post by: ponut64 on July 16, 2018, 02:04:52 am
That's interesting. That address is in high memory (you only have 752 KB / 376 sectors to use there in total and the program takes some of that). It isn't stopping on a sector, so I can see why the address is bad; it isn't an even divisor of 2048. Memory must be managed in sectors (2048 bytes / 2 KB) or else crashes like this will happen.
I don't know if that will help you. I suspect that trying to run any game code alongside the CPK system is going to cause problems...
Perhaps use "jo_core_add_callback" in an IF statement inside main to add the callback for the game code if pad1 presses a key. (you would trigger this with a bool that is set true when you hit the key, so you don't have to press it constantly)

Throw up your working folder, I'd like to look.
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 16, 2018, 02:18:27 am
I am already using callback for the video portion. I'm definitely running into problems with everything being in one file. I hadn't really considered running everything else using a callback. I wonder if I would need to run the rest in another file? I did try running the game in a header file attached to the video demo, but I couldn't get it to work. I also noticed there is a return to boot menu option, but I'm not sure how that works. I'll put up the files soon. When I do, I'll let you know. Once you grab them, I'll pull them down.
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 16, 2018, 02:32:47 am
Ponut, here is the zip file: http://www.mediafire.com/file/a65rene2ifl5fpi/SaturnTeam.zip/file (http://www.mediafire.com/file/a65rene2ifl5fpi/SaturnTeam.zip/file). Let me know when you've downloaded it, so I can take it down. Thanks!
Title: Re: How to autoload game after video
Post by: ponut64 on July 16, 2018, 03:11:22 am
I downloaded the demo.

You've got a few problems in this code, mainly too many callbacks. Way too many. You should be program-controlling whether or not things run inside a "game_loop" function. You shouldn't need more than 1 callback for the game, and 1 for the video. The bad pointer is because you are working with too many callbacks, and removing some of them. I don't want to be too harsh, you definitely have something, and I wish you the best of skills.

Secondly, BACKGROUND.H is consuming too much memory. To be precise, it is consuming about 600KB of high memory. There simply is not enough memory for the video to play when you include the background like that. Even if Jo engine is passing it off to VDP2, since it is included in the program itself, it is not an area available to memory allocation by default.

You MUST use binary files for ALL models, sprites, textures, and background data. To do this you should look at XL2's model loading tools and demos.
If you don't do this, you will continue to face mysterious crashes from SBL/SGL functions that basically destroy everything whenever they are out of sectors to run with, since Jo engine is front-loaded into high memory.
/e: When you move to program-controlled binary file loading, you should be able to use LWRAM for your project, even if the CPK eats up all of high memory you might not need that.
And, in that circumstance, your massive VDP2 background can be overwritten in LWRAM since it doesn't need to be there anymore.

Lastly, Jo Engine is not designed to have videos be program-controlled, as we thought it could be. You MUST load the CPK ONLY ONCE. Jo designed it to be a part of the program that is run, and then ignored. If it is inside a system callback, you're going to have trouble. As far as I have been able to test, this is the only correct way to play a video:

Code: [Select]
	jo_core_init(JO_COLOR_Black);
    if (jo_video_open_file("SAMPLE.CPK")){
        jo_video_play(video_stop);
}
jo_core_add_callback(my_video);

Your error code 101 is the following:
Code: [Select]
	CPK_ERR_OUT_OF_HANDLE		= 0x00000101,/* ハンドル売り切れ 			*/
Essentially that means when you have it as part of a system callback, too many CPK handles are created since it's running every frame.

I haven't fixed your problem, but hopefully I have armed you with enough information to proceed.

/e: a million edits
Title: Re: How to autoload game after video
Post by: SaturnTeam on July 16, 2018, 03:19:26 am
Okay. That's good feedback. I appreciate it. I'm still learning C, so it's a bit difficult. I had tried setting the global malloc in the makefile, and it always returned the problem of too much memory being eaten up. I'll work on lowering the background memory use. I see what you're saying about loading the video once. I couldn't figure out why it was only loaded in jo_main in the demo. So that makes sense.
Title: Re: How to autoload game after video
Post by: ponut64 on July 16, 2018, 03:23:26 am
I'm glad I can help, hopefully I did. Also, I've pushed a million edits to the post.
Title: Re: How to autoload game after video
Post by: logi on July 16, 2018, 06:38:46 pm
I have not really spent much time on this issue, but I have noticed one thing.

If I let the video play through and wait for the my_video_stopped() callback to be executed before I try to load the background image, then the out of memory error is thrown.

But if I manually stop the video using the jo_video_stop() function just 1 frame before the video ends and remove the callback, I am then able to load the background image into memory.
Although the video window is still being displayed over the background image it is not giving any memory errors.

https://youtu.be/LYE-Hb-WM8k

Code: [Select]
#include <jo/jo.h>
#include <jo/video.h>

int viedo_draw_id;
int video_counter;

void my_draw(void) {
video_counter += 1;

if (video_counter < 385) {
// Yes, it consume a lot of memory during playing :)
jo_printf(0, 0, "Dynamic memory usage: %d%%  ", jo_memory_usage_percent());
jo_printf(0, 1, "Sprite memory usage: %d%%  ", jo_sprite_usage_percent());
jo_printf(0, 5, jo_get_last_error());
jo_sprite_draw3D(jo_get_video_sprite(), 0, 0, 170);
}
else {
jo_core_remove_callback(viedo_draw_id);
jo_sprite_free_from(jo_get_video_sprite());
jo_video_stop();
my_background();
}
}

void my_background() {
jo_clear_screen();
        jo_img      bg;
        bg.data = NULL;
        jo_tga_loader(&bg, "BG", "BG.TGA", JO_COLOR_Transparent);
        jo_set_background_sprite(&bg, 0, 0);
        jo_free_img(&bg);
}

void  my_video_stopped(void) {

}

void jo_main(void) {
jo_core_init(JO_COLOR_Black);
video_counter = 0;

if (jo_video_open_file("SAMPLE.CPK"))
            jo_video_play(my_video_stopped);

viedo_draw_id = jo_core_add_callback(my_draw);
jo_core_run();
}

EDIT:
I also modified the 'RING_BUF_SIZ' in the video.c file, which is why the video is now consuming less dynamic memory.