Gamestudio Links
Zorro Links
Newest Posts
Blobsculptor tools and objects download here
by NeoDumont. 03/28/24 03:01
Issue with Multi-Core WFO Training
by aliswee. 03/24/24 20:20
Why Zorro supports up to 72 cores?
by Edgar_Herrera. 03/23/24 21:41
Zorro Trader GPT
by TipmyPip. 03/06/24 09:27
VSCode instead of SED
by 3run. 03/01/24 19:06
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (AndrewAMD, Nymphodora), 972 guests, and 8 spiders.
Key: Admin, Global Mod, Mod
Newest Members
sakolin, rajesh7827, juergen_wue, NITRO_FOREVER, jack0roses
19043 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 3 1 2 3
Preloading assets in the background #371304
05/19/11 19:17
05/19/11 19:17
Joined: Mar 2006
Posts: 3,538
WA, Australia
J
JibbSmart Offline OP
Expert
JibbSmart  Offline OP
Expert
J

Joined: Mar 2006
Posts: 3,538
WA, Australia
G'day!

I have two requests.

It'd be really cool to be able to preload models, sounds, levels, bmaps, and even arbitrary files in the background, over many frames (like how the http_ functions let the game continue while it waits for data). This could lead to huge levels that are loaded dynamically and all sorts of cool stuff. I imagine it could be used something like this (based on the http example code):
Code:
var id = load_asset("massivelyComplexEnt.mdl");
while (!load_ready(id)) wait(1);
if (load_ready(id) == 1) { // load successful?
	levelReady = 1; // global var to notify everyone the next room is ready
	ent_create("massivelyComplexEnt.mdl", nullvector, roomSetupAction);
} else {
	error("BIG MISTAKE!");
}

Unless, of course, is there already a way to safely do this with our own threading? An additional function to check if an asset has already been loaded or is in the process of being loaded would also be fantastic, but that kind of thing we can manage ourselves. Something like:
Originally Posted By: Imaginary Manual
load_status(var id)
Returns information about an asset's place in memory:

2 asset has already been loaded
1 asset is being loaded
0 asset has not been loaded

My second request is an option to not load the level anew when using session_connect or session_open (or any other session_ functions that require it). I guess this has to do with synchronising entities between sessions, but I'm sure I'm not the only one who sets dplay_entrate to -1 and synchronises everything manually with the send_data_ functions. It'd be nice to set a variable or something for these situations so levels don't need to be loaded again, and then use the session_ functions as we please without having to re-initialise levels. If you've played Burnout Paradise, a very cool features was that you could connect to a game and drop out of it without interrupting your driving, since it was all one big world, and all it had to do on the client side was synchronise a few players, and then remove them when you disconnect.

Thanks for reading laugh

Jibb


Formerly known as JulzMighty.
I made KarBOOM!
Re: Preloading assets in the background [Re: JibbSmart] #371309
05/19/11 19:45
05/19/11 19:45
Joined: Oct 2007
Posts: 5,210
İstanbul, Turkey
Quad Offline
Senior Expert
Quad  Offline
Senior Expert

Joined: Oct 2007
Posts: 5,210
İstanbul, Turkey
load_asset(string assetname,bool force_reload); could be better wink


3333333333
Re: Preloading assets in the background [Re: Quad] #371310
05/19/11 19:46
05/19/11 19:46
Joined: Oct 2007
Posts: 5,210
İstanbul, Turkey
Quad Offline
Senior Expert
Quad  Offline
Senior Expert

Joined: Oct 2007
Posts: 5,210
İstanbul, Turkey
load_status
return value 3 asset was already loaded, use force_reload to force reloading.


3333333333
Re: Preloading assets in the background [Re: Quad] #371314
05/19/11 19:49
05/19/11 19:49
Joined: Mar 2006
Posts: 3,538
WA, Australia
J
JibbSmart Offline OP
Expert
JibbSmart  Offline OP
Expert
J

Joined: Mar 2006
Posts: 3,538
WA, Australia
Yes ^^ That would be very useful for level editors, for example.

Jibb


Formerly known as JulzMighty.
I made KarBOOM!
Re: Preloading assets in the background [Re: JibbSmart] #371316
05/19/11 20:08
05/19/11 20:08
Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
MasterQ32 Offline
Expert
MasterQ32  Offline
Expert

Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
i think you can do something like loading assets wink
buffer_add and multithreading with winapi functions...


Visit my site: www.masterq32.de
Re: Preloading assets in the background [Re: MasterQ32] #371339
05/20/11 07:30
05/20/11 07:30
Joined: Jul 2001
Posts: 6,904
H
HeelX Offline
Senior Expert
HeelX  Offline
Senior Expert
H

Joined: Jul 2001
Posts: 6,904
Streaming content is one of those big things I can think of which are missing in Gamestudio. This counts for all kinds of stuff: Bitmaps, Models, Levels, Sounds, etc.

One further suggestion: If one would stream a content and creates it with the common functions like ent_create, the streaming will be continued until it is ready and then it will automatically created by the called function.

This way, one could start streaming e.g. the next level, if the player is in the reach of the level exit. So, lets say it is big and loaded by ~70% when the level_load call is done. Then, the level_load call would wait, until the remaining ~30% of the level is loaded and then it will be "activated".

Sounds reasonable, isn't it? smile

Re: Preloading assets in the background [Re: HeelX] #371348
05/20/11 10:02
05/20/11 10:02
Joined: Jul 2008
Posts: 894
T
TechMuc Offline
User
TechMuc  Offline
User
T

Joined: Jul 2008
Posts: 894
Streaming of 3DGS content is possible as richi007 already stated..

At least as long as buffer_add is thread-safe.. but this is a thing jcl has to answer..

Re: Preloading assets in the background [Re: TechMuc] #371351
05/20/11 10:22
05/20/11 10:22
Joined: Oct 2002
Posts: 806
Zapan@work Offline
User
Zapan@work  Offline
User

Joined: Oct 2002
Posts: 806
You should create a dll for this and sell it, Iam sure many people would like to have it!

Re: Preloading assets in the background [Re: Zapan@work] #371359
05/20/11 12:05
05/20/11 12:05
Joined: Apr 2007
Posts: 3,751
Canada
WretchedSid Offline
Expert
WretchedSid  Offline
Expert

Joined: Apr 2007
Posts: 3,751
Canada
Ahh, no one needs a dll and taking money for something this trivial brings bad karma (imo)

Here you go, a working version. It calls add_buffer() on the mainthread, so no need to fear anything. Just save it into a file and include it. Done.
Code:
#include <windows.h>
#include <stdio.h>

typedef struct entA_state
{
	char loaded; // 0 = not begun loading, 1 = loading, 2 = loaded, 3 = Added, 200 = Fuckup
	void *buffer;
	long size;
	
	char *file;
	char *filepath;
	
	struct entA_state *next;
} entA_state;

HANDLE entA_mutex;
entA_state *entA_firstState;

DWORD entA_worker(void *unused);

int entA_init()
{
	entA_firstState 	= NULL;
	entA_mutex 			= CreateMutex(NULL, FALSE, NULL);
	
	if(entA_mutex == NULL)
	{
		return 0;	
	}
	
	DWORD threadID;
	
	// TODO: Error checking
	CreateThread(NULL, 0, entA_worker, NULL, 0, &threadID);
	SetThreadPriority(threadID, THREAD_PRIORITY_LOWEST);	
	
	return 1;
}


DWORD entA_loadObject(entA_state *state)
{
	FILE *file = fopen(state->filepath, "rb");
	if(!file)
	{
		// BAD BAD BAD
		WaitForSingleObject(entA_mutex, INFINITE);
		state->loaded = 200;
		ReleaseMutex(entA_mutex);
		
		return 1;
	}
	
	// Get the size of the file
	fseek(file, 0, SEEK_END);
   state->size = ftell(file);
   rewind(file);
	
	// TODO: Error checking
	state->buffer = (void *)malloc(state->size);
	fread(state->buffer, 1, state->size, file);
	
	fclose(file);


	WaitForSingleObject(entA_mutex, INFINITE);
	state->loaded = 2; // We are done, hooray!
	ReleaseMutex(entA_mutex);

	return 1;
}

DWORD entA_worker(void *unused)
{
	while(1)
	{
		WaitForSingleObject(entA_mutex, INFINITE);
		
		entA_state *state = entA_firstState;
		while(state)
		{
			if(state->loaded == 0)
			{
				state->loaded = 1;
				CreateThread(NULL, 0, entA_loadObject, state, 0, NULL);
			}
			
			state = state->next;
		}
		
		ReleaseMutex(entA_mutex);
	}
	
	return 1;
}

entA_state *entA_stateForFile(char *file, char *filepath)
{
	entA_state *state = entA_firstState;
	while(state)
	{
		if(strcmp(file, state->file) == 0)
		{
			return state;
		}
		
		state = state->next;
	}
	
	state = (entA_state *)malloc(sizeof(entA_state));
	if(state)
	{
		state->file = (char *)malloc((strlen(file) + 1) * sizeof(char));
		state->filepath = (char *)malloc((strlen(filepath) + 1) * sizeof(char));
		
		strcpy(state->file, file);
		strcpy(state->filepath, filepath);
		
		state->loaded 	= 0;
		state->buffer 	= NULL;
		state->next 	= NULL;
		
		state->next = entA_firstState;
		entA_firstState = state;
	}
	
	return state;
}

ENTITY *entA_create(STRING *file, VECTOR *pos, EVENT entAction)
{
	STRING		*filepath;
	ENTITY 		*ent = NULL;
	entA_state 	*state;
	int initiatedLoading = 0;

	filepath = str_create(work_dir);
	str_cat(filepath, "\\");
	str_cat(filepath, file);

	
	WaitForSingleObject(entA_mutex, INFINITE);
	state = entA_stateForFile(_chr(file), _chr(filepath));
	
	if(state->loaded == 3)
	{
		// The file is already cached, so we can safely create the entity right away
		ReleaseMutex(entA_mutex);
		
		ptr_remove(filepath);
		return ent_create(file, pos, entAction);
	}
	else if(state->loaded == 0)
	{
		// We have kicked of the loading, so its our responsibility to add the buffer later on
		initiatedLoading = 1;
	}
	
	ReleaseMutex(entA_mutex);

	int ready = 0;
	while(ready == 0)
	{
		wait(1);
		
		WaitForSingleObject(entA_mutex, INFINITE);
		switch(state->loaded)
		{
			case 2:
			{
				if(initiatedLoading == 1)
				{
					add_buffer(state->file, state->buffer, state->size);
					state->loaded = 3;
					ready = 1;
				}
			}
				break;
				
			case 3:
			{
				ready = 1;
			}
				break;
			
			case 200:
			{
				printf("Could not load file \"%s\"", state->file);
				ReleaseMutex(entA_mutex);
				
				ptr_remove(filepath);
				return NULL;
			}
				break;
			
			default:
				break;
		}
		
		ReleaseMutex(entA_mutex);
	}
	
	ent = ent_create(file, pos, entAction);
	
	ptr_remove(filepath);	
	return ent;
}



There are some error checkings left and I there is no way to purge the files (well they can be purged, but not recreated). Its trivial to add these things, so I let you do this. Here is a small test scrip which uses the models from the shadertest folder:
Code:
#include <acknex.h>
#include "async.c"

ENTITY *stone, *marine;

action rotate()
{
	while(1)
	{
		my.pan += 12 * time_step;
		my.tilt += 9 * time_step;
		
		wait(1);
	}
}

void main()
{
	level_load(NULL);
	wait(1);
	
	entA_init(); // DON'T forget!
	
	
	stone = entA_create("stones.mdl", vector(1024, 0, 0), NULL);
	marine = entA_create("marine.mdl", vector(1024, 0, 0), rotate);
	
	int i;
	for(i=0; i<10; i++)
		entA_create("box.mdl", vector(1024, -290 + (i * 120), -35), NULL);
}



Last edited by JustSid; 05/20/11 12:19.

Shitlord by trade and passion. Graphics programmer at Laminar Research.
I write blog posts at feresignum.com
Re: Preloading assets in the background [Re: WretchedSid] #371363
05/20/11 12:40
05/20/11 12:40
Joined: Jul 2000
Posts: 27,977
Frankfurt
jcl Offline

Chief Engineer
jcl  Offline

Chief Engineer

Joined: Jul 2000
Posts: 27,977
Frankfurt
I can confirm that add_buffer is thread safe, and can be used for preloading assets in a separate thread.

Page 1 of 3 1 2 3

Moderated by  aztec, Spirit 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1