Files
wagic/JGE/src/JFileSystem.cpp
T
Xawotihs 832904dce1 - Defined keys translation for SDL config
- Added boost thread files, that fixes all the threading/compiling/linking problems on Android ...
- Added opengles 1.1 code, there are still some bugs I need to tackle ... and I should realy split this file now !!!
- Added Android debug traces
- Hardcoded resources to "/sdcard/Wagic/Res" for the moment on Android
- Added a wagic SDL project for desktop, and the related SDL frontend used for Android. This frontend is currently mostly desktop based, it needs some work to be fully useable with touch and gesture on Android.
2011-04-23 21:30:36 +00:00

289 lines
6.1 KiB
C++

//-------------------------------------------------------------------------------------
//
// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows.
//
// Licensed under the BSD license, see LICENSE in JGE root for details.
//
// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) <jhkhui@gmail.com>
//
//-------------------------------------------------------------------------------------
#ifdef WIN32
#pragma warning(disable : 4786)
#endif
#include "../include/JGE.h"
#include "../include/JFileSystem.h"
#include "../include/JLogger.h"
#include "tinyxml/tinyxml.h"
#include "unzip/unzip.h"
#include <stdio.h>
#include <vector>
#include <map>
#include <string>
JZipCache::JZipCache()
{}
JZipCache::~JZipCache()
{
map<string,unz_file_pos *>::iterator it;
for (it = dir.begin(); it != dir.end(); ++it)
{
delete(it->second);
}
dir.clear();
}
void JFileSystem::preloadZip(const string& filename)
{
map<string,JZipCache *>::iterator it = mZipCache.find(filename);
if (it != mZipCache.end()) return;
JZipCache * cache = new JZipCache();
mZipCache[filename] = cache;
if (!mZipAvailable || !mZipFile)
{
AttachZipFile(filename);
if (!mZipAvailable || !mZipFile) return;
}
int err = unzGoToFirstFile (mZipFile);
while (err == UNZ_OK)
{
unz_file_pos* filePos = new unz_file_pos();
char filenameInzip[4096];
if (unzGetCurrentFileInfo(mZipFile, NULL, filenameInzip, sizeof(filenameInzip), NULL, 0, NULL, 0) == UNZ_OK)
{
unzGetFilePos(mZipFile, filePos);
string name = filenameInzip;
cache->dir[name] = filePos;
}
err = unzGoToNextFile(mZipFile);
}
}
JFileSystem* JFileSystem::mInstance = NULL;
JFileSystem* JFileSystem::GetInstance()
{
if (mInstance == NULL)
{
mInstance = new JFileSystem();
}
return mInstance;
}
void JFileSystem::Destroy()
{
if (mInstance)
{
delete mInstance;
mInstance = NULL;
}
}
JFileSystem::JFileSystem()
{
mZipAvailable = false;
#if defined (PSP)
mFile = -1;
#else
mFile = NULL;
#endif
mPassword = NULL;
mZipFile = NULL;
mFileSize = 0;
#ifdef RESPATH
SetResourceRoot(RESPATH"/");
#else
SetResourceRoot("Res/"); // default root folder
#endif
}
JFileSystem::~JFileSystem()
{
DetachZipFile();
map<string,JZipCache *>::iterator it;
for (it = mZipCache.begin(); it != mZipCache.end(); ++it){
delete(it->second);
}
mZipCache.clear();
}
bool JFileSystem::AttachZipFile(const string &zipfile, char *password /* = NULL */)
{
if (mZipAvailable && mZipFile != NULL)
{
if (mZipFileName != zipfile)
DetachZipFile(); // close the previous zip file
else
return true;
}
mZipFileName = zipfile;
mPassword = password;
mZipFile = unzOpen(mZipFileName.c_str());
if (mZipFile != NULL)
{
mZipAvailable = true;
return true;
}
return false;
}
void JFileSystem::DetachZipFile()
{
if (mZipAvailable && mZipFile != NULL)
{
int error = unzCloseCurrentFile(mZipFile);
if (error < 0 )
JLOG("error calling unzCloseCurrentFile");
error = unzClose(mZipFile);
if (error < 0)
JLOG("Error calling unzClose");
}
mZipFile = NULL;
mZipAvailable = false;
}
bool JFileSystem::OpenFile(const string &filename)
{
string path = mResourceRoot + filename;
if (mZipAvailable && mZipFile != NULL)
{
preloadZip(mZipFileName);
map<string,JZipCache *>::iterator it = mZipCache.find(mZipFileName);
if (it == mZipCache.end())
{
DetachZipFile();
return OpenFile(filename);
}
JZipCache * zc = it->second;
map<string,unz_file_pos *>::iterator it2 = zc->dir.find(filename);
if (it2 == zc->dir.end())
{
DetachZipFile();
return OpenFile(filename);
}
unzGoToFilePos(mZipFile,it2->second);
char filenameInzip[256];
unz_file_info fileInfo;
if (unzGetCurrentFileInfo(mZipFile, &fileInfo, filenameInzip, sizeof(filenameInzip), NULL, 0, NULL, 0) == UNZ_OK)
mFileSize = fileInfo.uncompressed_size;
else
mFileSize = 0;
return (unzOpenCurrentFilePassword(mZipFile, mPassword) == UNZ_OK);
}
else
{
#if defined (PSP)
mFile = sceIoOpen(path.c_str(), PSP_O_RDONLY, 0777);
if (mFile > 0)
{
mFileSize = sceIoLseek(mFile, 0, PSP_SEEK_END);
sceIoLseek(mFile, 0, PSP_SEEK_SET);
return true;
}
#else
mFile = fopen(path.c_str(), "rb");
if (mFile != NULL)
{
fseek(mFile, 0, SEEK_END);
mFileSize = ftell(mFile);
fseek(mFile, 0, SEEK_SET);
return true;
}
#endif
}
return false;
}
void JFileSystem::CloseFile()
{
if (mZipAvailable && mZipFile != NULL)
{
unzCloseCurrentFile(mZipFile);
return;
}
#if defined (PSP)
if (mFile > 0)
sceIoClose(mFile);
#else
if (mFile != NULL)
fclose(mFile);
#endif
}
int JFileSystem::ReadFile(void *buffer, int size)
{
if (mZipAvailable && mZipFile != NULL)
{
return unzReadCurrentFile(mZipFile, buffer, size);
}
else
{
#if defined (PSP)
return sceIoRead(mFile, buffer, size);
#else
return fread(buffer, 1, size, mFile);
#endif
}
}
int JFileSystem::GetFileSize()
{
return mFileSize;
}
void JFileSystem::SetResourceRoot(const string& resourceRoot)
{
#ifdef IOS
NSString *pathUTF8 = [NSString stringWithUTF8String: resourceRoot.c_str()];
NSString *fullpath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:pathUTF8];
mResourceRoot = [fullpath cStringUsingEncoding:1];
mResourceRoot += "/";
#elif defined (ANDROID)
mResourceRoot = "/sdcard/Wagic/Res/";
#else
mResourceRoot = resourceRoot;
#endif
}
string JFileSystem::GetResourceRoot()
{
return mResourceRoot;
}
string JFileSystem::GetResourceFile(string filename)
{
string result = mResourceRoot;
return result.append(filename);
}