|
SDLGameEngine
|
00001 /* 00002 * Copyright (c) 2007 Heiko Irrgang 00003 * 00004 * The license and distribution terms for this file may be 00005 * found in the file COPYING in this distribution or at 00006 * http://93-interactive.com/cms/products/software/sdl-game-engine/license/ 00007 */ 00008 00009 #include <sge.h> 00010 00011 #define SGEIMAGE_VIDEO 0 00012 #define SGEIMAGE_MEMORY 1 00013 00014 static Uint32 sgeReadEncryptedUint32(FILE *f, const char *encryptionkey) { 00015 Uint32 ret; 00016 size_t result; 00017 result=fread(&ret,1,sizeof(Uint32),f); 00018 sgeDecryptBuffer(&ret, sizeof(Uint32), encryptionkey); 00019 ret=sgeByteSwap32(ret); 00020 return ret; 00021 } 00022 00023 static void sgeWriteEncryptedUint32(FILE *f, Uint32 value, const char *encryptionkey) { 00024 Uint32 tmp; 00025 size_t result; 00026 tmp=sgeByteSwap32(value); 00027 sgeEncryptBuffer(&tmp, sizeof(Uint32), encryptionkey); 00028 result=fwrite(&tmp, 1, sizeof(Uint32), f); 00029 } 00030 00031 SGEFILE *sgeOpenFile(const char *filename, const char *encryptionkey) { 00032 int i; 00033 SGEFILE *ret; 00034 Uint32 *namelens; 00035 Uint32 *namepos; 00036 char *namebuf=NULL; 00037 size_t result; 00038 00039 sgeNew(ret,SGEFILE); 00040 ret->f=fopen(filename,"rb"); 00041 if (!ret->f) sgeBailOut("could not open file: %s\n",filename); 00042 00043 ret->encryptionkey=strdup(encryptionkey); 00044 ret->archname=strdup(filename); 00045 00046 fseek(ret->f, -sizeof(Uint32), SEEK_END); 00047 ret->numberOfFiles=sgeReadEncryptedUint32(ret->f, encryptionkey); 00048 00049 sgeMalloc(namelens, Uint32, ret->numberOfFiles); 00050 sgeMalloc(namepos, Uint32, ret->numberOfFiles); 00051 00052 sgeMalloc(ret->fileName,char *,ret->numberOfFiles); 00053 sgeMalloc(ret->position,Uint32,ret->numberOfFiles); 00054 sgeMalloc(ret->fileSize,Uint32,ret->numberOfFiles); 00055 00056 fseek(ret->f, -(ret->numberOfFiles*sizeof(Uint32)*4+sizeof(Uint32)), SEEK_END); 00057 00058 for (i=0;i<ret->numberOfFiles;i++) { 00059 namepos[i]=sgeReadEncryptedUint32(ret->f, encryptionkey); 00060 namelens[i]=sgeReadEncryptedUint32(ret->f, encryptionkey); 00061 ret->position[i]=sgeReadEncryptedUint32(ret->f, encryptionkey); 00062 ret->fileSize[i]=sgeReadEncryptedUint32(ret->f, encryptionkey); 00063 } 00064 00065 for (i=0;i<ret->numberOfFiles;i++) { 00066 fseek(ret->f, namepos[i], SEEK_SET); 00067 if (namebuf!=NULL) sgeFree(namebuf); 00068 sgeMalloc(namebuf, char, namelens[i]+1); 00069 result=fread(namebuf, 1, namelens[i], ret->f); 00070 sgeDecryptBuffer(namebuf, namelens[i], encryptionkey); 00071 ret->fileName[i]=strdup(namebuf); 00072 } 00073 if (namebuf!=NULL) sgeFree(namebuf); 00074 00075 sgeFree(namelens); 00076 sgeFree(namepos); 00077 rewind(ret->f); 00078 00079 return ret; 00080 } 00081 00082 void sgeCloseFile(SGEFILE *f) { 00083 int i; 00084 00085 fclose(f->f); 00086 00087 for (i=0;i<f->numberOfFiles;i++) { 00088 sgeFree(f->fileName[i]); 00089 } 00090 sgeFree(f->archname); 00091 sgeFree(f->fileName); 00092 sgeFree(f->position); 00093 sgeFree(f->fileSize); 00094 sgeFree(f->encryptionkey); 00095 00096 sgeFree(f); 00097 } 00098 00099 void sgeEncryptBuffer(void *buffer, Uint32 length, const char *encryptionkey) { 00100 int j; 00101 unsigned char *buf=buffer; 00102 Uint32 keylen=strlen(encryptionkey); 00103 for (j=0;j<length;j++) { 00104 buf[j]^=encryptionkey[j%(keylen+1)]; 00105 j++; 00106 } 00107 } 00108 00109 void sgeCreateFile(const char *filename, char *filenames[], Uint32 numberOfFiles, const char *encryptionkey) { 00110 int i; 00111 FILE *f,*d; 00112 struct stat st; 00113 Uint32 *fileSizes; 00114 Uint32 *filePositions; 00115 Uint32 *namePositions; 00116 char *buf=NULL; 00117 char *namebuf=NULL; 00118 size_t result; 00119 00120 f=fopen(filename,"wb"); 00121 if (!f) sgeBailOut("cannot create %s\n", filename); 00122 00123 sgeMalloc(fileSizes,Uint32,numberOfFiles); 00124 sgeMalloc(filePositions,Uint32,numberOfFiles); 00125 sgeMalloc(namePositions,Uint32,numberOfFiles); 00126 00127 for (i=0;i<numberOfFiles;i++) { 00128 stat(filenames[i],&st); 00129 namePositions[i]=ftell(f); 00130 fileSizes[i]=st.st_size; 00131 00132 if (namebuf==NULL) sgeFree(namebuf); 00133 sgeMalloc(namebuf,char,strlen(filenames[i])+1); 00134 namebuf=strdup(filenames[i]); 00135 sgeEncryptBuffer(namebuf, strlen(filenames[i]), encryptionkey); 00136 result=fwrite(namebuf, 1, strlen(filenames[i]), f); 00137 00138 filePositions[i]=ftell(f); 00139 d=fopen(filenames[i],"rb"); 00140 if (!d) sgeBailOut("cannot open %s\n", filenames[i]); 00141 00142 sgeMalloc(buf,char,fileSizes[i]); 00143 result=fread(buf,1,fileSizes[i],d); 00144 sgeEncryptBuffer(buf, fileSizes[i], encryptionkey); 00145 result=fwrite(buf,1,fileSizes[i],f); 00146 sgeFree(buf); 00147 00148 fclose(d); 00149 } 00150 if (namebuf==NULL) sgeFree(namebuf); 00151 00152 for (i=0;i<numberOfFiles;i++) { 00153 sgeWriteEncryptedUint32(f, namePositions[i], encryptionkey); 00154 sgeWriteEncryptedUint32(f, strlen(filenames[i]), encryptionkey); 00155 sgeWriteEncryptedUint32(f, filePositions[i], encryptionkey); 00156 sgeWriteEncryptedUint32(f, fileSizes[i], encryptionkey); 00157 } 00158 sgeWriteEncryptedUint32(f, numberOfFiles, encryptionkey); 00159 fflush(f); 00160 fclose(f); 00161 00162 sgeFree(fileSizes); 00163 sgeFree(filePositions); 00164 sgeFree(namePositions); 00165 } 00166 00167 int sgeGetFileIndex(SGEFILE *f, const char *filename) { 00168 int i; 00169 for (i=0;i<f->numberOfFiles;i++) { 00170 if (strcmp(filename, f->fileName[i])==0) { 00171 return i; 00172 } 00173 } 00174 sgeBailOut("file not found: %s\n", filename); 00175 } 00176 00177 Uint32 sgeGetFileSize(SGEFILE *f, const char *filename) { 00178 int i=sgeGetFileIndex(f, filename); 00179 return f->fileSize[i]; 00180 } 00181 00182 void *sgeReadFile(SGEFILE *f, const char *filename) { 00183 int i=sgeGetFileIndex(f, filename); 00184 unsigned char *ret; 00185 sgeMalloc(ret, unsigned char, f->fileSize[i]+1); 00186 fseek(f->f,f->position[i],SEEK_SET); 00187 if (fread(ret,1,f->fileSize[i],f->f)==0) { 00188 sgeBailOut("error reading %s from archive\n",filename); 00189 } 00190 sgeDecryptBuffer(ret, f->fileSize[i], f->encryptionkey); 00191 return (void *)ret; 00192 } 00193 00194 static SDL_Surface *sgeReadImageHelper(SGEFILE *f, const char *filename, int type) { 00195 SDL_RWops *rw; 00196 char *d=sgeReadFile(f,filename); 00197 SDL_Surface *s, *ret; 00198 00199 rw=SDL_RWFromMem(d, sgeGetFileSize(f, filename)); 00200 s=IMG_Load_RW(rw,0); 00201 if (s==NULL) sgeBailOut("reading image '%s' failed\n",filename); 00202 SDL_FreeRW(rw); 00203 sgeFree(d); 00204 00205 if (type==SGEIMAGE_MEMORY) { 00206 return s; 00207 } 00208 00209 ret=SDL_DisplayFormatAlpha(s); 00210 if (ret!=NULL) { 00211 SDL_FreeSurface(s); 00212 return ret; 00213 } 00214 00215 return s; 00216 } 00217 00218 SDL_Surface *sgeReadImage(SGEFILE *f, const char *filename) { 00219 return sgeReadImageHelper(f, filename, SGEIMAGE_VIDEO); 00220 } 00221 00222 SDL_Surface *sgeReadImageMemory(SGEFILE *f, const char *filename) { 00223 return sgeReadImageHelper(f, filename, SGEIMAGE_MEMORY); 00224 } 00225 00226 Mix_Chunk *sgeReadSound(SGEFILE *f, const char *filename) { 00227 SDL_RWops *rw; 00228 char *d=sgeReadFile(f,filename); 00229 Mix_Chunk *s; 00230 00231 rw=SDL_RWFromMem(d, sgeGetFileSize(f, filename)); 00232 s=Mix_LoadWAV_RW(rw,0); 00233 if (s==NULL) sgeBailOut("reading sound '%s' failed\n",filename); 00234 SDL_FreeRW(rw); 00235 sgeFree(d); 00236 return s; 00237 } 00238 00239 SDL_Surface *sgeDuplicateSDLSurface(SDL_Surface *s) { 00240 Uint32 origflags; 00241 SDL_Surface *ret=SDL_CreateRGBSurface(s->flags, s->w, s->h, s->format->BitsPerPixel, s->format->Rmask, s->format->Gmask, s->format->Bmask, s->format->Amask); 00242 origflags=s->flags; 00243 s->flags&=!SDL_SRCALPHA; 00244 SDL_BlitSurface(s, NULL, ret, NULL); 00245 s->flags=origflags; 00246 return ret; 00247 }