Merge branch 'io'
[cantaveria.git] / loader.c
blob371f46c34d3ae216fae6e1612bb1c1fa876d4012
1 /*
2 Cantaveria - action adventure platform game
3 Copyright (C) 2009 2010 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stdio.h>
29 #include <list.h>
30 #include <loader.h>
31 #include <util.h>
32 #include <zip.h>
34 struct reader {
35 zip_file* f;
36 int next_c;
39 zip_archive* arc;
42 void loader_init(){
43 char* filename = "data.zip";
44 arc = zip_aropenf(filename);
45 if(arc == NULL){
46 fatal_error("loader: unable to load data archive \"%s\" (%s)\n", filename, zip_geterror());
48 boot_msg("loader: ... OK\n");
51 void loader_quit(){
52 zip_arclose(arc);
55 reader* data_open(char* dir, char* filename){
56 char buf[1024];
57 strcpy(buf, dir);
58 strcat(buf, filename);
59 return loader_open(buf);
62 reader* loader_open(char* filename){
63 char buf[1024] = "data/";
64 int L = strlen(buf);
65 strncpy(buf+L,filename,1024-L);
66 buf[1023] = 0;
68 reader* rd = xmalloc(sizeof(reader));
69 rd->f = zip_fopen(arc, filename);
70 if(!rd->f){
71 error_msg("loader_open: can't open %s (%s)\n", filename, zip_geterror());
72 free(rd);
73 return NULL;
75 return rd;
79 void loader_close(reader* rd){
80 zip_fclose(rd->f);
81 free(rd);
85 int loader_read(reader* rd, void* buf, int count){
86 int n = zip_fread(rd->f, buf, count);
87 if(n < 0){
88 error_msg("loader_read: %s\n", zip_geterror());
89 return -1;
91 return n;
94 unsigned char* loader_readall(char* filename, int* size){
95 reader* rd = loader_open(filename);
96 if(!rd) return NULL;
98 /* somehow read all of rd into a buffer and return it */
100 /* FIXME */
101 error_msg("loader_readall: not yet implemented\n");
102 return NULL;
105 int loader_readline(reader* rd, char* buf, int size){
106 char c;
107 int i = 0;
108 int n;
110 while(i < size){
111 n = loader_read(rd, &c, 1);
112 if(n == 0){ /* end of file */
113 buf[i] = '\0';
114 return 0;
117 if(n < 0){
118 error_msg("loader_readline: %s\n", zip_geterror());
119 return -1;
122 if(c == '\r'){ /* CRLF ? */
123 n = loader_read(rd, &c, 1);
124 if(n == 0){ /* file ended with CR... well take it */
125 buf[i] = '\0';
126 return 0;
129 if(n < 0){
130 error_msg("loader_readline: %s\n", zip_geterror());
131 return -1;
134 if(c != '\n'){
135 error_msg("loader_readline: I cannot read lines ending in CR and not CRLF\n");
136 return -1;
139 buf[i] = '\0';
140 return 0;
143 if(c == '\n'){ /* LF */
144 buf[i] = '\0';
145 return 0;
148 buf[i] = c;
149 i += 1;
152 error_msg("loader_readline: buffer size too small\n");
153 return 0;
156 int loader_scanline(reader* rd, char* format, ...){
157 char buf[256] = "";
158 va_list ap;
159 int ret;
161 if(loader_readline(rd, buf, 256) < 0){
162 return -1;
165 va_start(ap, format);
166 ret = vsscanf(buf,format,ap);
167 va_end(ap);
169 return ret;
175 /*binary i/o*/
176 int read_byte(reader* rd){
177 unsigned char c = 0;
178 loader_read(rd, &c, 1);
179 return c;
182 int read_short(reader* rd){
183 unsigned char c[2] = {0,0};
184 loader_read(rd, c+0, 1);
185 loader_read(rd, c+1, 1);
186 return (c[0]<<8) | c[1];
189 int read_int(reader* rd){
190 unsigned char c[4] = {0,0,0,0};
191 loader_read(rd, c+0, 1);
192 loader_read(rd, c+1, 1);
193 loader_read(rd, c+2, 1);
194 loader_read(rd, c+3, 1);
195 return (c[0]<<24) | (c[1]<<16) | (c[2]<<8) | c[3];
198 char* read_string(reader* rd){
199 unsigned int L = read_int(rd);
200 if(L==0) return NULL;
201 char* S = xmalloc(L+1);
202 S[L] = '\0';
203 loader_read(rd, S, L);
204 return S;
209 list* loader_readdir(char* path){
210 zip_dir* dir = zip_opendir(arc, path);
211 if(dir == NULL){
212 error_msg("loader_readdir: unable to open '%s' (%s)\n",
213 path, zip_geterror());
214 return NULL;
217 list* dirs = empty();
218 while(1){
219 char* entry = zip_readdir(dir);
220 if(entry == NULL) break;
221 else push(dirs, entry);
224 return dirs;
227 void loader_freedirlist(list* dirs){
228 recycle(dirs);