Sega Saturn Development > General Jo Engine Help

Usage of GFS_NwFread (you probably expected this...)

(1/6) > >>

ponut64:
Hey,

I've got the GFS_NwFread function and structure from the Workshop 95 slides, and it compiles and "runs".
Of course what I am trying to do is use it to read XL2's ZTP files, which have segmented data meant for a modelData_t struct.

It seems XL2 loads these in segments with GFS_Load, loading one segment has information relevant to loading the next segment.
Of course I'm here because I don't understand how exactly that works, I'm guessing the reason this doesn't work with GFS_NwFread is because I'm not arranging the memory addresses right.
I say that because it doesn't load any of the other models using the current Address variable called after my dysfunctional '"ztFileStream" function is run.

I imagine all I should need to do is read from the buffer into the address for a modelData_t struct...
..
but i don't know how to do that...

/e: Oh, you should probably know that the function is in ZT_LOAD_MODEL.c  in ZT folder.


--- Code: ---
//Experimental
void * ztFileStream(Sint8 * filename, void * startAddress, entity_t * model)
{

    memset_l((void*)startAddress,0x0000, (0xFFFE - ((Uint32)startAddress-(Uint32)LWRAM)));  //Not 100% necessary, since data can just be overwritten, but good for testing and see how much data a level takes
    void * currentAddress;
    currentAddress = startAddress;

    Sint32 fid = GFS_NameToId((Sint8*)filename);
GfsHn gfs;
Sint32 stat;
Sint32 nsct;
Sint32 bsize;
//Model Data is the destination of data.
modelData_t bufModel;
//Destination address?
    void * ptr = &bufModel;

//Loading follows
gfs = GFS_Open(fid);
//Get sectors
GFS_GetFileSize(gfs, nsct, NULL, NULL);
bsize = 2048 * nsct;
// nsct = GFS_ByteToSct(gfs, bytesOf);

//modelData_t has an assumed size?
GFS_NwFread(gfs, nsct, (Uint32*)currentAddress, bsize);

//For loop is blank because this will run until GFS_Close, AKA always run until GFS_Close.
for(;;)
{
stat = GFS_NwExecOne(gfs);
if(stat == GFS_SVR_COMPLETED)
{
break;
}
//Copy gfs to modelData_t bufmodel???
memcpy_l((Sint32*)ptr, (Sint32*)(startAddress), (sizeof(modelData_t)));

/**ADDED**/
model->pos[X]=bufModel.Origin[X]; model->pos[Y]=bufModel.Origin[Y]; model->pos[Z]=bufModel.Origin[Z];
model->length[X]=bufModel.Length[X]; model->length[Y]=bufModel.Length[Y]; model->length[Z]=bufModel.Length[Z];
model->nbMeshes=bufModel.TOTAL_MESH;

//Get textures from GFS
Uint16 first_texture = loadTextures(startAddress, &bufModel);
//Get PDATA from GFS
// Sint32 bytesOff = (bufModel.TEXT_SIZE+(sizeof(modelData_t)))/2048;

// bytesOff = bufModel.TEXT_SIZE+(sizeof(modelData_t)) - (bytesOff*2048);
// currentAddress = (void*)(currentAddress + bytesOff);

currentAddress = loadPDATA((void*)currentAddress, model, &bufModel);
//Set textures from GFS
setTextures(first_texture, model, bufModel.TOTAL_MESH, true);

    return currentAddress;
}
GFS_Close(gfs);

}
--- End code ---

XL2:
I didn't take a huge look.
For the function, I never used it myself, but I think the Jo Engine async loading uses it, so you should look there.
You don't need to load small segments since I aligned all the model data to just be dumped in memory, which is way faster.
You also return before closing the file, which is wrong.

ponut64:
Returning before closing the file.. yeah that one is on me, I should have known that would halt the function and thus halt the CD system on that file.
That change, plus commenting everything else out, allows everything else to load as normal.

Jo engine ASYNC loading does in fact use NwFread so I will look that over.

/e
It looks to me whether using what I've written or what Jo engine does, I'd just need to get the read data where its supposed to go.
Could be handled in the callback in the jo engine async read function or in that part of the written code between break and GFS close.

ponut64:
Upon further reading, I can't think of why this would not work.
What happens? It does not load. All loading stops.


--- Code: ---
//Experimental
void * ztFileStream(Sint8 * filename, void * startAddress, entity_t * model, Sint8 dummy)
{

    memset_l((void*)startAddress,0x0000, (0xFFFE - ((Uint32)startAddress-(Uint32)LWRAM)));  //Not 100% necessary, since data can just be overwritten, but good for testing and see how much data a level takes
    void * currentAddress;
    currentAddress = startAddress;

    Sint32 fid = GFS_NameToId((Sint8*)filename);
GfsHn gfs;
Sint32 stat;
Sint32 nsct;
Sint32 bsize;
//Model Data is the destination of data.
modelData_t bufModel;
//Destination address?
    void * ptr = &bufModel;

//Loading follows
gfs = GFS_Open(fid);
//Get sectors
GFS_GetFileSize(gfs, &nsct, NULL, NULL);
bsize = 2048 * nsct;
// nsct = GFS_ByteToSct(gfs, bytesOf);

//modelData_t has an assumed size?
GFS_NwFread(gfs, nsct, (Uint32*)currentAddress, bsize);

//For loop is blank because this will run until GFS_Close, AKA always run until GFS_Close.
for(;;)
{
stat = GFS_NwExecOne(gfs);
if(stat == GFS_SVR_COMPLETED)
{
break;
}
//Copy gfs to modelData_t bufmodel???
memcpy_l((Sint32*)ptr, (Sint32*)(startAddress), (sizeof(modelData_t)));

    /**ADDED**/
    model->pos[X]=bufModel.Origin[X]; model->pos[Y]=bufModel.Origin[Y]; model->pos[Z]=bufModel.Origin[Z];
    model->length[X]=bufModel.Length[X]; model->length[Y]=bufModel.Length[Y]; model->length[Z]=bufModel.Length[Z];
    model->nbMeshes=bufModel.TOTAL_MESH;

    /**Load the texture list (using an offset to allow DMA transfer)**/
    Uint16 first_texture = loadTextures(startAddress, &bufModel);

    /**Load PDATA**/
    Sint32 bytesOff = bufModel.TEXT_SIZE+(sizeof(modelData_t)) - (bytesOff*2048);
    currentAddress = (void*)(currentAddress + bytesOff);

    currentAddress = loadPDATA((void*)currentAddress, model, &bufModel);

    /**Set textures**/
    setTextures(first_texture, model, bufModel.TOTAL_MESH, true);


}
GFS_Close(gfs);
    return currentAddress;

}
--- End code ---

So what do we do:

1 - we set a new address so we don't overwrite the last data
2 - that address is now the current address
3 - we get a file ID from the file name
4 - variable and struct setup
? I question why bufModel is modelData_t and not entity_t, tried it one way or another it doesn't function properly
5 - Set GFS and GFS handler
6 - Get the file size in sectors, we don't need anything else (they are NULL).
6 - Set the size in bytes based on the sector size
7 - Queue the command NwFread for the file with current Address as the buffer area
8 - Execute NwFread in the open gfs
9 - When the server is complete with the file, stop the execution and
10 - memcpy destination bufModel, the source startAddress (which has never been set separate from currentAddress at this point BUT setting it to current causes unknown code crash), the size copied is the size of... you know.
? Why would current crash when it is no different from start...
? It doesn't crash or halt if everything past memcpy before GFS_Close is commented out.
11 What follows,
taking the contents of the buffered model data and putting it into the model which is the desired entity_t struct.

Truly, I know I don't really understand what is happening. Especially not enough to make a callback that could put the binary data into an entity_t struct from the Jo engine async read function.
I'm thinking in a forum post.

XL2:
I didn't look at it for very long, but you put everything in your loop.
It loads textures and everything you don't need and loops these functions over, causing crashes.
In think you should just ditch the loop, load data until textures like I did, then start the async loading using the sector offset that I already had.
Then just load all the data in the cd buffer, wait until it's done and then fetch the data to your start address.
You could then call the other functions.
I never played with streaming functions, but the cd ram buffer can hold 512 KB (crazy that they put so much ram there and the Saturn still had crappy video support).
For your animations, it just wouldn't work, but you could try with images, maybe allowing you some kind of pseudo Resident Evil game where you could always cache the next backgrounds in RAM and transfert it to VRAM when you swap backgrounds.

Navigation

[0] Message Index

[#] Next page

Sitemap 1 2 3 4 5 6 7 8 9 10 
Go to full version