loading from memory

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
grassblade
Posts: 27
Joined: Mon Jan 09, 2006 11:17 am

loading from memory

Post by grassblade »

Hello all,
I have an already loaded zip file in memory. Is there any way I could use this in the file system?
I tried to overload irrlicht CFileSystem::addZipFileArchive code to something like this

Code: Select all

bool CFileSystem::addZipFileArchive(void* mmemory, s32 msize,const c8* mfilename,bool deleteMemoryWhenDropped, bool ignoreCase, bool ignorePaths)
{

IReadFile* file = createMemoryReadFile( mmemory, msize, mfilename,deleteMemoryWhenDropped);
	if (file)
	{
		CZipReader* zr = new CZipReader(file, ignoreCase, ignorePaths);
		if (zr)...................

It loads and compiles. I tried to use it like this.

Code: Select all

device->getFileSystem()->addZipFileArchive(memblocktest,sizetest,"inmemory.zip");
Then load material from it.Everything compiles, but no texture. What am I doing wrong?
I don't quite understand the c8* filename in parameter. Is the filename is there to be used as a reference as a path?I have also used ifstream::pos_type for the size parameter. I divided it by 4 to get at s32.
Will some experts show me the right way from my amatuerish attempts? Thanks in advance.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I don't quite understand the c8* filename in parameter.
The filename parameter passed to the original addZipFileArchive() was the name of the file to open. The filename passed to createMemoryReadFile() call is just used by the memory read file so that it can return something meaningful when someone calls getFileName(). In this case the memory read file is just a temporary, so nobody will really be using it other than the CZipReader.
I divided it by 4 to get at s32.
That is very likely to be causing problems. Just cast it to an s32 and hope that your memory buffer is less than 4GB in size. :)

Travis
grassblade
Posts: 27
Joined: Mon Jan 09, 2006 11:17 am

Post by grassblade »

Thanks for the answer. But the problem seems to be not with the casting. As you have said the ifstream::pos_type is an s32 value. I am posting the complete code please have a look. I tried writing the zip back and the zip is OK.

Code: Select all

#include <irrlicht.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

ifstream::pos_type sizetest;
char * memblocktest;
 
int loadzip()
{
       
  ifstream file ("input.zip",ios::in|ios::binary|ios::ate);        
  ofstream myfile("output.zip",ios::out|ios::binary);
  if (file.is_open())
  {
    sizetest = file.tellg();
   
    memblocktest = new char [sizetest];
    file.seekg (0, ios::beg);
    file.read (memblocktest, sizetest);
    file.close();
   
    myfile.write (memblocktest,sizetest);
    myfile.close();

   cout<<"Sizetest:"<<sizetest<<endl;
   cout<<"Sizetests32:"<<(s32)sizetest<<endl;
   //delete[] memblocktest;

  }
  else cout << "Unable to open file";
  
  return 0;
}


int mymain();//all irrlicht stuff

int main()
{

loadzip();
mymain();

}


int mymain()
{
 			IrrlichtDevice *device =
		createDevice(EDT_SOFTWARE, dimension2d<s32>(640, 480), 16,
			false, false, false, 0);

	device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");

	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();




	IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );

//device->getFileSystem()->addZipFileArchive("test.zip");
//virtual bool addZipFileArchive(void* memory, s32 size, const c8* fileName, bool deleteMemoryWhenDropped=true,  bool ignoreCase = true, bool ignorePaths = true);

device->getFileSystem()->addZipFileArchive(memblocktest,sizetest,"inmemory.zip");


	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setFrameLoop(0, 310);
	//	node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
		node->setMaterialTexture( 0, driver->getTexture("e7panelwood.jpg") );//a file from the loaded zip

	}


	smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

	while(device->run())
	{

		driver->beginScene(true, true, SColor(255,100,101,140));

		smgr->drawAll();
		guienv->drawAll();

		driver->endScene();
	}


	device->drop();
	delete[] memblocktest;
 
	return 0;
}
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Works just fine for me. You might look to the console window to see what failed, or better yet, bust out the debugger and step into the code. :)

Code: Select all

FILE* f = fopen("test.zip", "rb");
if (f != 0)
{
   // get the size
   fseek(f, 0, SEEK_END);
   s32 size = ftell(f);
   fseek(f, 0, SEEK_SET);

   char* mem = new char[size];
   fread(mem, 1, size, f);

   device->getFileSystem()->addZipFileArchive("test.zip", mem, size, true);

   fclose(f);
}

video::IImage* image = driver->createImageFromFile("alien.bmp");
printf("image %s loaded\n", image ? "is" : "is not");

if (image)
   image->drop();
grassblade
Posts: 27
Joined: Mon Jan 09, 2006 11:17 am

Post by grassblade »

:D .It works. My problem was perhaps the void*.
As for Debugging, I am an amatuer programmer, is only trying to learn hard. Have to learn how to debug properly.
Thank you Vitek for the help.
EvIl_DeViL
Posts: 89
Joined: Tue Nov 06, 2007 4:49 pm

Post by EvIl_DeViL »

it can't be done without overloading the CZipReader and recompiling the engine simple using the standard APIs?

what about

Code: Select all

IFileSystem* filesys = device->getFileSystem(); 
   IReadFile* myFile = filesys->createAndOpenFile("file.zip"); 
   u32 fileSize =  myFile->getSize(); 
   printf("file size: %d\n",fileSize);    
   IReadFile* myRamFile = filesys->createMemoryReadFile(myFile, fileSize ,"ramfile.zip", true); 
   const c8* ramFileName = myRamFile->getFileName(); 
   const c8* fileName = myFile->getFileName(); 
   printf("ramfilename: %s filename: %s\n",ramFileName,fileName); 
   stringc curdir= filesys->getFileDir("ramfile.zip"); 
   const c8* chars = curdir.c_str(); 
   stringc curabsdir = filesys->getAbsolutePath("ramfile.zip"); 
   const c8* chars2 = curabsdir.c_str(); 
   printf("relative path: %s absolute path: %s\n",chars,chars2); 
   const c8* pwd = filesys->getWorkingDirectory(); 
   printf("current directory: %s\n",pwd); 
   bool esit = filesys->existFile(/*myRamFile->getFileName()*/ chars2); 
    printf("%s can %sbe opened\n",chars2/*myRamFile->getFileName()*/,esit?"":"not "); 
   esit = filesys->addZipFileArchive("ramfile.zip"); 
     printf("archive %sloaded\n",esit?"":"not ");
what's wrong? addzipfile can't find ramfile.zip... where's the mistake?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

EvIl_DeViL wrote:

Code: Select all

   IFileSystem* filesys = device->getFileSystem(); 

   IReadFile* myRamFile = filesys->createMemoryReadFile(myFile, fileSize ,"ramfile.zip", true); 

   filesys->addZipFileArchive("ramfile.zip"); 
what's wrong? addzipfile can't find ramfile.zip... where's the mistake?
The mistake is that you don't know what you're doing.

If you call createAndOpenFile() that will create a physical file on the hard disk. If you call createMemoryReadFile() that creates a block of memory of memory that is accessible through an IReadFile interface. It doesn't actually create a file.

In order for your code to work, you'd have to write the contents of myRamFile out to disk...

Code: Select all

IWriteFile* file = filesys->createAndWriteFile("ramfile.zip", false);
file->write(...); // write the data backing your memory read file
file->drop();
Then you get to use the file system to reopen the physical file.

Code: Select all

filesys->addZipFileArchive("ramfile.zip");
That is why the discussion was about creating a zip archive from a block of memory and the solution involved modifying Irrlicht.

Travis
EvIl_DeViL
Posts: 89
Joined: Tue Nov 06, 2007 4:49 pm

Post by EvIl_DeViL »

but i don't want that if my game crash the file remain on the disk... i want to load a file in ram, process it and add it by the addZipFile...
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Dude, I'm telling you that Irrlicht, without modification, cannot load a zip file archive from memory. The function addZipFileArchive() only loads files from disk. If you don't write the file to disk, you won't be able to load it. Period.

I don't know why you think your app will crash if you load a file from disk, but I wish you'd stop cross posting to every thread that you think is related to your problem. I've seen several posts from you in topics that you've revived in the last two days. If you have a problem, you should create a thread, tell of the problem that you're having, what you've tried, and then, if necessary link to related threads that you think may be useful. People will answer if they can help.

Travis
EvIl_DeViL
Posts: 89
Joined: Tue Nov 06, 2007 4:49 pm

Post by EvIl_DeViL »

i'm trying to create a child public class... something like

Code: Select all

class myFileArchive : public irr::io::CFileSystem
if there will be some result i'll post in the other thread (when finished i'll post the link here for don't spam)

about the cross posting... i opened a thread about the file size (totally an other thing), a thread about loading file from memory, and ask something here... i don't see this several post and thread you said...[/code]
CodyCer0
Posts: 41
Joined: Mon Dec 08, 2008 3:07 am

I'm sorry...

Post by CodyCer0 »

I'm sorry for bumping such an old post but I am suffering a similar problem but unfortunately I'm an irrlicht dummy and can't really understand to much about some of the code you have up there.

I am trying to use bin2h to do this exact thing but I don't know how to put the file into practice from the point of getting it in there... It isn't like your code really. But this is the code I'm trying.

Code: Select all

#include <irrlicht.h>
#include "BuildInSydneyModel.h"
#include "BuildInSydneyTexture.h"


using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

IReadFile* file;
IReadFile* file2;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

int main()
{
	IrrlichtDevice *device =
#ifdef _IRR_OSX_PLATFORM_
		createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 16,
			false, false, false, 0);
#else
		createDevice( video::EDT_SOFTWARE, dimension2d<s32>(640, 480), 16,
			false, false, false, 0);
#endif

	device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
	const c8* filename2 = "sydneyModel";
	const c8* filename = "sydneyModelTexture";

	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();

	guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!",
		rect<s32>(10,10,260,22), true);
	file = device->getFileSystem()->createMemoryReadFile(mySydneyTextureData, mySydneyTextureData_size, filename, false);
	file2 = device->getFileSystem()->createMemoryReadFile(mySydneyModelData, mySydneyModelData_size, filename2, false);

	IAnimatedMesh* mesh = smgr->getMesh(file2);
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );

	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setMD2Animation ( scene::EMAT_STAND );
		node->setMaterialTexture( 0, driver->getTexture(file) );
	}

	smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

	while(device->run())
	{

		driver->beginScene(true, true, SColor(255,100,101,140));

		smgr->drawAll();
		guienv->drawAll();

		driver->endScene();
	}

	device->drop();

	return 0;
}
and I keep getting this in the commandline area...

Code: Select all

MD2 Loader: Wrong file header: sydneyModel
Could not load mesh, wrong file format seems to be unsupported: sydneyModel

As a little explanation, the name shouldn't really matter because I'm not trying to use the actual file as the memory but a header file that contains data from the bin2h exported header, with a few minor edits.

Also I have tried so many different names that I think it all leads back to it not being read right.

Maybe perhaps it isn't being read right because I am not doing something right in the header, I guess I'll try to store the data into memory from the file itself.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Re: I'm sorry...

Post by vitek »

CodyCer0 wrote:As a little explanation, the name shouldn't really matter because I'm not trying to use the actual file as the memory but a header file that contains data from the bin2h exported header, with a few minor edits.
This is another problem where a debugger can help a bunch. Just step into the getMesh() call and you'll be able to see what is going on.

It looks like the MD2 loader is being used to load the model data, so Irrlicht has figured out that the data you're providing is indeed an MD2 model. It appears to be failing because the loader failed to read the MD2 header or data correctly. This is probably because you've modified it incorrectly.

Travis.
CodyCer0
Posts: 41
Joined: Mon Dec 08, 2008 3:07 am

Post by CodyCer0 »

I admit I'm an irrlicht noob and don't know if I set up he headers right. (Meaning I couldn't set up the demo example if I tried)

I can't show you it at all because I'm at school right now. Also the file size of sydney model was big which made the array generated by bin2h like god 20000+ (Idk) characters long. So I can't even post the whole thing, although I might be able to upload the file somewhere and give you a link to download it once I get home.
grassblade
Posts: 27
Joined: Mon Jan 09, 2006 11:17 am

Post by grassblade »

Thie following code works. Test it. If needed I can post the full code.

Code: Select all

 IReadFile * binmesh=device->getFileSystem()->createMemoryReadFile(sydney, 302128, "mesh.md2");//instead of manually adding the size you can get it through code
.....
IAnimatedMesh* mesh = smgr->getMesh(binmesh);
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
CodyCer0
Posts: 41
Joined: Mon Dec 08, 2008 3:07 am

Post by CodyCer0 »

grassblade wrote:Thie following code works. Test it. If needed I can post the full code.

Code: Select all

 IReadFile * binmesh=device->getFileSystem()->createMemoryReadFile(sydney, 302128, "mesh.md2");//instead of manually adding the size you can get it through code
.....
IAnimatedMesh* mesh = smgr->getMesh(binmesh);
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
I'm sorry but I do need it in full, I don't know what sydney in

Code: Select all

binmesh=device->getFileSystem()->createMemoryReadFile(sydney, 302128, "mesh.md2");
is refering to.[/code]
Post Reply