00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "physfs/physfs_sdl.hpp"
00018
00019 #include <physfs.h>
00020 #include <sstream>
00021 #include <stdexcept>
00022 #include <assert.h>
00023
00024 #include "util/log.hpp"
00025
00026 static int funcSeek(struct SDL_RWops* context, int offset, int whence)
00027 {
00028 PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
00029 int res;
00030 switch(whence) {
00031 case SEEK_SET:
00032 res = PHYSFS_seek(file, offset);
00033 break;
00034 case SEEK_CUR:
00035 res = PHYSFS_seek(file, PHYSFS_tell(file) + offset);
00036 break;
00037 case SEEK_END:
00038 res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
00039 break;
00040 default:
00041 res = 0;
00042 assert(false);
00043 break;
00044 }
00045 if(res == 0) {
00046 log_warning << "Error seeking in file: " << PHYSFS_getLastError() << std::endl;
00047 return -1;
00048 }
00049
00050 return (int) PHYSFS_tell(file);
00051 }
00052
00053 static int funcRead(struct SDL_RWops* context, void* ptr, int size, int maxnum)
00054 {
00055 PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
00056
00057 int res = PHYSFS_read(file, ptr, size, maxnum);
00058 return res;
00059 }
00060
00061 static int funcClose(struct SDL_RWops* context)
00062 {
00063 PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
00064
00065 PHYSFS_close(file);
00066 delete context;
00067
00068 return 0;
00069 }
00070
00071 SDL_RWops* get_physfs_SDLRWops(const std::string& filename)
00072 {
00073
00074
00075 if(filename == "") {
00076 throw std::runtime_error("Couldn't open file: empty filename");
00077 }
00078
00079 PHYSFS_file* file = (PHYSFS_file*) PHYSFS_openRead(filename.c_str());
00080 if(!file) {
00081 std::stringstream msg;
00082 msg << "Couldn't open '" << filename << "': "
00083 << PHYSFS_getLastError();
00084 throw std::runtime_error(msg.str());
00085 }
00086
00087 SDL_RWops* ops = new SDL_RWops();
00088 ops->type = 0;
00089 ops->hidden.unknown.data1 = file;
00090 ops->seek = funcSeek;
00091 ops->read = funcRead;
00092 ops->write = 0;
00093 ops->close = funcClose;
00094 return ops;
00095 }
00096
00097