Add copyright message to gles_video
[gpsp.git] / zip.c
CommitLineData
2823a4c8 1/* gameplaySP
2 *
3 * Copyright (C) 2006 Exophase <exophase@gmail.com>
4 * Copyright (C) 2006 SiberianSTAR
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
2823a4c8 21#include "common.h"
8b6232a6 22#include <zlib.h>
2823a4c8 23
24#define ZIP_BUFFER_SIZE (128 * 1024)
25
26struct SZIPFileDataDescriptor
27{
28 s32 CRC32;
29 s32 CompressedSize;
30 s32 UncompressedSize;
31} __attribute__((packed));
32
33struct SZIPFileHeader
34{
35 char Sig[4]; // EDIT: Used to be s32 Sig;
36 s16 VersionToExtract;
37 s16 GeneralBitFlag;
38 s16 CompressionMethod;
39 s16 LastModFileTime;
40 s16 LastModFileDate;
41 struct SZIPFileDataDescriptor DataDescriptor;
42 s16 FilenameLength;
43 s16 ExtraFieldLength;
44} __attribute__((packed));
45
46u32 load_file_zip(char *filename)
47{
48 struct SZIPFileHeader data;
bbba3209 49 char tmp[1024];
2823a4c8 50 s32 retval = -1;
51 u8 *buffer = NULL;
52 u8 *cbuffer;
bbba3209 53 char *ext;
a88b0431 54 int ret;
2823a4c8 55
56 file_open(fd, filename, read);
57
58 if(!file_check_valid(fd))
59 return -1;
60
a88b0431 61 while (1)
2823a4c8 62 {
a88b0431 63 ret = file_read(fd, &data, sizeof(data));
64 if (ret != sizeof(data))
65 break;
66
67 // It checks for the following: 0x50 0x4B 0x03 0x04 (PK..)
68 if( data.Sig[0] != 0x50 || data.Sig[1] != 0x4B ||
69 data.Sig[2] != 0x03 || data.Sig[3] != 0x04 )
70 {
71 break;
72 }
73
74 ret = file_read(fd, tmp, data.FilenameLength);
75 if (ret != data.FilenameLength)
76 break;
77
2823a4c8 78 tmp[data.FilenameLength] = 0; // end string
79
80 if(data.ExtraFieldLength)
81 file_seek(fd, data.ExtraFieldLength, SEEK_CUR);
82
83 if(data.GeneralBitFlag & 0x0008)
84 {
85 file_read(fd, &data.DataDescriptor,
86 sizeof(struct SZIPFileDataDescriptor));
87 }
88
89 ext = strrchr(tmp, '.') + 1;
90
91 // file is too big
92 if(data.DataDescriptor.UncompressedSize > gamepak_ram_buffer_size)
a88b0431 93 goto skip;
2823a4c8 94
95 if(!strcasecmp(ext, "bin") || !strcasecmp(ext, "gba"))
96 {
97 buffer = gamepak_rom;
98
99 // ok, found
100 switch(data.CompressionMethod)
101 {
102 case 0:
103 retval = data.DataDescriptor.UncompressedSize;
104 file_read(fd, buffer, retval);
2823a4c8 105 goto outcode;
106
107 case 8:
108 {
109 z_stream stream;
110 s32 err;
111
112 cbuffer = malloc(ZIP_BUFFER_SIZE);
113
114 stream.next_in = (Bytef*)cbuffer;
115 stream.avail_in = (u32)ZIP_BUFFER_SIZE;
116
117 stream.next_out = (Bytef*)buffer;
118
a88b0431 119 // EDIT: Now uses proper conversion of data types for retval.
120 retval = (u32)data.DataDescriptor.UncompressedSize;
121 stream.avail_out = data.DataDescriptor.UncompressedSize;
2823a4c8 122
123 stream.zalloc = (alloc_func)0;
124 stream.zfree = (free_func)0;
125
126 err = inflateInit2(&stream, -MAX_WBITS);
127
128 file_read(fd, cbuffer, ZIP_BUFFER_SIZE);
129
130 if(err == Z_OK)
131 {
132 while(err != Z_STREAM_END)
133 {
134 err = inflate(&stream, Z_SYNC_FLUSH);
135 if(err == Z_BUF_ERROR)
136 {
137 stream.avail_in = ZIP_BUFFER_SIZE;
138 stream.next_in = (Bytef*)cbuffer;
139 file_read(fd, cbuffer, ZIP_BUFFER_SIZE);
140 }
141 }
142 err = Z_OK;
143 inflateEnd(&stream);
144 }
145 free(cbuffer);
146 goto outcode;
147 }
148 }
149 }
a88b0431 150
151skip:
152 file_seek(fd, data.DataDescriptor.CompressedSize, SEEK_CUR);
2823a4c8 153 }
154
155outcode:
156 file_close(fd);
157
158 return retval;
159}