]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_map.c
merged mapread files w
[16.git] / src / lib / 16_map.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 \r
23 #include "src/lib/16_map.h"\r
24 \r
25 // Ideally, preprocess json during compilation and read serialized data\r
26 \r
27 int jsoneq(const char *json, jsmntok_t *tok, const char *s) {\r
28         if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&\r
29                         strncmp(json + tok->start, s, tok->end - tok->start) == 0) {\r
30                 return 0;\r
31         }\r
32         return -1;\r
33 }\r
34 \r
35 //this function is quite messy ^^; sorry! it is a quick and dirty fix~\r
36 word dump(const char *js, jsmntok_t *t, size_t count, word indent, char *js_sv, map_t *map, dword q) {\r
37         dword i;\r
38         word j;//, k;\r
39         bitmap_t bp;\r
40         #ifdef DEBUG_JS\r
41         if(indent==0)\r
42         {\r
43                 fprintf(stdout, "%s\n", js);\r
44                 fprintf(stdout, "\n");\r
45         }\r
46         #endif\r
47         #ifdef DEBUG_DUMPVARS\r
48         fprintf(stdout, "t->size=[%d]   ", t->size);\r
49         fprintf(stdout, "q=[%d] ", q);\r
50         fprintf(stdout, "indent= [%d]   ", indent);\r
51         fprintf(stdout, "js_sv= [%s]\n", js_sv);\r
52         #endif\r
53         if (count == 0) {\r
54                 return 0;\r
55         }\r
56         /* We may want to do strtol() here to get numeric value */\r
57 //0000fprintf(stderr, "t->type=%d\n", t->type);\r
58         if (t->type == JSMN_PRIMITIVE) {\r
59                 if(strstr(js_sv, "data"))\r
60                 {\r
61                         /*\r
62                                 here we should recursivly call dump again here to skip over the array until we get the facking width of the map.\r
63                                 so we can initiate the map which allocates the facking map->tiles->data->data properly and THEN we can return\r
64                                 here to read the data.... That is my design for this... wwww\r
65 \r
66                                 FUCK well i am stuck.... wwww\r
67                         */\r
68                         map->data[q] = (byte)atoi(js+t->start);\r
69                         #ifdef DEBUG_MAPDATA\r
70                                 fprintf(stdout, "%d[%d]", q, map->data[q]);\r
71                         #endif\r
72                 }\r
73                 else\r
74                 if(strstr(js_sv, "height"))\r
75                 {\r
76                         map->height = atoi(js+t->start);\r
77                         #ifdef DEBUG_MAPVAR\r
78                         fprintf(stdout, "indent= [%d]   ", indent);\r
79                         fprintf(stdout, "h:[%d]\n", map->height);\r
80                         #endif\r
81                 }else if(strstr(js_sv, "width"))\r
82                 {\r
83                         map->width = atoi(js+t->start);\r
84                         #ifdef DEBUG_MAPVAR\r
85                         fprintf(stdout, "indent= [%d]   ", indent);\r
86                         fprintf(stdout, "w:[%d]\n", map->width);\r
87                         #endif\r
88                 }\r
89                 return 1;\r
90                 /* We may use strndup() to fetch string value */\r
91         } else if (t->type == JSMN_STRING) {\r
92                 if(jsoneq(js, t, "data") == 0)\r
93                 {\r
94 //                      fprintf(stdout, "[[[[%d|%d]]]]\n", &(t+1)->size, (t+1)->size);\r
95 //                      fprintf(stdout, "\n%.*s[xx[%d|%d]xx]\n", (t+1)->end - (t+1)->start, js+(t+1)->start, &(t+1)->size, (t+1)->size);\r
96                         map->data = malloc(sizeof(byte) * (t+1)->size);\r
97                         map->tiles = malloc(sizeof(tiles_t));\r
98                         map->tiles->btdata = malloc(sizeof(bitmap_t));\r
99                         //fix this to be far~\r
100 //0000                  bp = bitmapLoadPcx("data/ed.pcx");\r
101 //                      bp = bitmapLoadPcx("data/koishi^^.pcx");\r
102                         map->tiles->btdata = &bp;\r
103 //----                  map->tiles->data = planar_buf_from_bitmap(&bp);\r
104                         //map->tiles->data->data = malloc((16/**2*/)*16);\r
105                         //map->tiles->data->width = (16/**2*/);\r
106                         //map->tiles->data->height= 16;\r
107                         map->tiles->tileHeight = 16;\r
108                         map->tiles->tileWidth = 16;\r
109                         map->tiles->rows = 1;\r
110                         map->tiles->cols = 1;\r
111                         map->tiles->debug_text=false;\r
112                         strcpy(js_sv, "data");//strdup(js+t->start);//, t->end - t->start);\r
113                 }\r
114                 else\r
115                 if (jsoneq(js, t, "height") == 0 && indent<=1)\r
116                 {\r
117                         strcpy(js_sv, "height");//strdup(js+t->start);//, t->end - t->start);\r
118                 }else\r
119                 if(jsoneq(js, t, "width") == 0 && indent<=1)\r
120                 {\r
121                         strcpy(js_sv, "width");//strdup(js+t->start);//, t->end - t->start);\r
122                 }else strcpy(js_sv, "\0");\r
123                 return 1;\r
124         } else if (t->type == JSMN_OBJECT) {\r
125                 //fprintf(stdout, "\n");\r
126                 j = 0;\r
127                 for (i = 0; i < t->size; i++) {\r
128                         //for (k = 0; k < indent; k++) fprintf(stdout, "\t");\r
129                         j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
130                         //fprintf(stdout, ": ");\r
131                         j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
132                         //fprintf(stdout, "\n");\r
133                 }\r
134                 return j+1;\r
135         } else if (t->type == JSMN_ARRAY) {\r
136                 j = 0;\r
137                 //fprintf(stdout, "==\n");\r
138                 for (i = 0; i < t->size; i++) {\r
139                         //for (k = 0; k < indent-1; k++) fprintf(stdout, "\t");\r
140                         //fprintf(stdout, "\t-");\r
141                         j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
142                         //fprintf(stdout, "==\n");\r
143                 }\r
144                 return j+1;\r
145         }\r
146         return 0;\r
147 }\r
148 \r
149 int loadmap(char *mn, map_t *map)\r
150 {\r
151         int r;\r
152         static word incr=0;\r
153         int eof_expected = 0;\r
154         char *js = NULL;\r
155         size_t jslen = 0;\r
156         char buf[BUFSIZ];\r
157         static char js_ss[16];\r
158 \r
159         jsmn_parser p;\r
160         jsmntok_t *tok;\r
161         size_t tokcount = 2;\r
162 \r
163         FILE *fh = fopen(mn, "r");\r
164 \r
165         /* Prepare parser */\r
166         jsmn_init(&p);\r
167 \r
168         /* Allocate some tokens as a start */\r
169 //0000fprintf(stderr, "tok malloc\n");\r
170         tok = malloc(sizeof(*tok) * tokcount);\r
171         if (tok == NULL) {\r
172                 fprintf(stderr, "malloc(): errno=%d\n", errno);\r
173                 return 3;\r
174         }\r
175 \r
176         for (;;) {\r
177                 /* Read another chunk */\r
178 //0000fprintf(stderr, "read\n");\r
179                 r = fread(buf, 1, sizeof(buf), fh);\r
180                 if (r < 0) {\r
181                         fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);\r
182                         return 1;\r
183                 }\r
184                 if (r == 0) {\r
185                         if (eof_expected != 0) {\r
186                                 return 0;\r
187                         } else {\r
188                                 fprintf(stderr, "fread(): unexpected EOF\n");\r
189                                 return 2;\r
190                         }\r
191                 }\r
192 //0000fprintf(stdout, "r=       [%d]    BUFSIZ=%d\n", r, BUFSIZ);\r
193 //0000fprintf(stderr, "js alloc~\n");\r
194                 js = realloc(js, jslen + r + 1);\r
195                 if (js == NULL) {\r
196                         fprintf(stderr, "*js=%Fp\n", *js);\r
197                         fprintf(stderr, "realloc(): errno = %d\n", errno);\r
198                         return 3;\r
199                 }\r
200                 strncpy(js + jslen, buf, r);\r
201                 jslen = jslen + r;\r
202 \r
203 again:\r
204 //0000fprintf(stdout, " parse~ tok=%zu  jslen=%zu       r=%d    _memavl()=%u    BUFSIZ=%d~\n", tokcount, jslen, r, _memavl(), BUFSIZ);\r
205 //0000fprintf(stdout, "p=[%u]   [%u]    [%d]\n", p.pos, p.toknext, p.toksuper);\r
206 /*\r
207                 I think it crashes on the line below when it tries to parse the data of huge maps... wwww this is a jsmn problem wwww\r
208 */\r
209                 r = jsmn_parse(&p, js, jslen, tok, tokcount);\r
210 //0000fprintf(stdout, "r=       [%d]\n", r);\r
211                 if (r < 0) {\r
212                         if (r == JSMN_ERROR_NOMEM) {\r
213                                 tokcount = tokcount * 2;\r
214 //0000fprintf(stderr, "tok realloc~ %zu\n", tokcount);\r
215                                 tok = realloc(tok, sizeof(*tok) * tokcount);\r
216                                 if (tok == NULL) {\r
217                                         fprintf(stderr, "realloc(): errno=%d\n", errno);\r
218                                         return 3;\r
219                                 }\r
220                                 goto again;\r
221                         }\r
222                 } else {\r
223                         //printf("js=%Fp\n", (js));\r
224                         //printf("*js=%Fp\n", (*(js)));\r
225                         //printf("&*js=%s\n", &(*(js)));\r
226                         //printf("&buf=[%Fp]\n", &buf);\r
227                         //printf("&buf_seg=[%x]\n", FP_SEG(&buf));\r
228                         //printf("&buf_off=[%x]\n", FP_OFF(&buf));\r
229                         //printf("&buf_fp=[%Fp]\n", MK_FP(FP_SEG(&buf), FP_OFF(&buf)));\r
230                         //printf("buf=[\n%s\n]\n", buf);\r
231                         //printf("buff=[%Fp]\n", buff);\r
232                         //printf("(*buff)=[%Fp]\n", (*buff));\r
233                         //printf("&(*buff)=[\n%s\n]\n", &(*buff));\r
234                         #ifdef DEBUG_DUMPVARS\r
235                         fprintf(stdout, "running dump~\n");\r
236                         #endif\r
237                         dump(js, tok, p.toknext, incr, &js_ss, map, 0);\r
238                         eof_expected = 1;\r
239                 }\r
240         }\r
241 \r
242         //free(js);\r
243         //free(tok);\r
244         //fclose(fh);\r
245 \r
246         return 0;\r
247 }\r
248 \r
249 void extract_map(const char *js, jsmntok_t *t, size_t count, map_t *map) {\r
250         int i, j, k, indent=0, inner_end;\r
251         bitmap_t bp;\r
252         //char *s;\r
253         i = 0;\r
254         while(i<count) {\r
255                 if(jsoneq(js, &(t[i]), "layers") == 0) {\r
256                         i++;\r
257                         map->layerdata = malloc(sizeof(byte*) * t[i].size);\r
258                         inner_end = t[i].end;\r
259                         k = 0;\r
260                         while(t[i].start < inner_end) {\r
261                                 printf("%d, %d\n", t[i].start, inner_end);\r
262                                 if(jsoneq(js, &(t[i]), "data") == 0) {\r
263                                         #ifdef DEBUG_MAPVAR\r
264                                         printf("Layer %d data: [", k);\r
265                                         #endif\r
266                                         map->layerdata[k] = malloc(sizeof(byte) * t[i+1].size);\r
267                                         for(j = 0; j < t[i+1].size; j++) {\r
268                                                 map->layerdata[k][j] = (byte)atoi(js + t[i+2+j].start);\r
269                                                 #ifdef DEBUG_MAPVAR\r
270                                                 printf("%d, ", map->layerdata[k][j]);\r
271                                                 #endif\r
272                                         }\r
273                                         i += j + 2;\r
274                                         k++;\r
275                                         #ifdef DEBUG_MAPVAR\r
276                                         puts("]");\r
277                                         #endif\r
278                                 }\r
279                                 else{\r
280                                         i++;\r
281                                 }\r
282                         }\r
283                 }\r
284                 if(jsoneq(js, &(t[i]), "tilesets") == 0) {\r
285                         i++;\r
286                         map->tiles = malloc(sizeof(tiles_t*) * t[i].size);\r
287                         inner_end = t[i].end;\r
288                         k = 0;\r
289                         while(t[i].start < inner_end) {\r
290                                 if(jsoneq(js, &(t[i]), "image") == 0) {\r
291                                         //fix this to be far~\r
292                                         map->layertile[k] = malloc(sizeof(tiles_t));\r
293                                         map->layertile[k]->btdata = malloc(sizeof(bitmap_t));\r
294                                         map->layertile[k]->tileHeight = 16;\r
295                                         map->layertile[k]->tileWidth = 16;\r
296                                         map->layertile[k]->rows = 1;\r
297                                         map->layertile[k]->cols = 1;\r
298                                         map->layertile[k]->debug_text=false;\r
299                                         //Fix to load tileset specified.\r
300                                         //And move to vrs, probably\r
301                                         //bp = bitmapLoadPcx("data/ed.pcx");\r
302                                         map->layertile[k]->btdata = &bp;\r
303                                         k++;\r
304                                 }\r
305                                 i++;\r
306                         }\r
307                 }\r
308 \r
309                 if (jsoneq(js, &(t[i]), "height") == 0 && indent<=1) {\r
310                         map->height = atoi(js + t[i+1].start);\r
311                         #ifdef DEBUG_MAPVAR\r
312                         printf("Height: %d\n", map->height);\r
313                         #endif\r
314                         i++;\r
315                 }\r
316                 else if(jsoneq(js, &(t[i]), "width") == 0 && indent<=1) {\r
317                         map->width = atoi(js + t[i+1].start);\r
318                         #ifdef DEBUG_MAPVAR\r
319                         printf("Width: %d\n", map->width);\r
320                         #endif\r
321                         i++;\r
322                 }\r
323                 i++;\r
324         }\r
325 }\r
326 \r
327 int newloadmap(char *mn, map_t *map) {\r
328         char *js;\r
329 \r
330         jsmn_parser p;\r
331         jsmntok_t *tok = NULL;\r
332         size_t tokcount, file_s;\r
333 \r
334         FILE *fh = fopen(mn, "r");\r
335         int status;\r
336 \r
337         /* Prepare parser */\r
338         jsmn_init(&p);\r
339 \r
340         file_s = filesize(fh);\r
341         js = malloc(file_s);\r
342         if(js == NULL) {\r
343                 fprintf(stderr, "malloc(): errno = %d", 2);\r
344                 fclose(fh);\r
345                 return 3;\r
346         }\r
347         if(fread(js, 1, file_s, fh) != file_s) {\r
348                 fprintf(stderr, "Map read error");\r
349                 free(js);\r
350                 fclose(fh);\r
351                 return 1;\r
352         }\r
353         tokcount = jsmn_parse(&p, js, file_s, NULL, 0);\r
354         tok = malloc(tokcount*sizeof(jsmntok_t));\r
355         printf("Allocated %d tokens", tokcount);\r
356         jsmn_init(&p);\r
357         if((status = jsmn_parse(&p, js, file_s, tok, tokcount)) < 0)\r
358         {\r
359                 printf("Error: %d\n", status);\r
360                 return status;\r
361         }\r
362         else if(status != tokcount) { printf("Warning: used %d tok\n", status);}\r
363         extract_map(js, tok, tokcount, map);\r
364 \r
365         free(js);\r
366         free(tok);\r
367         fclose(fh);\r
368 \r
369         return 0;\r
370 }\r