]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_map.c
WWWWWWWWWWWWwwwwwwwwwwWWWWWWWwwwwWWwwWWwwWwwWww
[16.git] / src / lib / 16_map.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2017 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 #ifdef __DEBUG_MAP__\r
112                         dbg_maptext=false;\r
113 #endif\r
114                         strcpy(js_sv, "data");//strdup(js+t->start);//, t->end - t->start);\r
115                 }\r
116                 else\r
117                 if (jsoneq(js, t, "height") == 0 && indent<=1)\r
118                 {\r
119                         strcpy(js_sv, "height");//strdup(js+t->start);//, t->end - t->start);\r
120                 }else\r
121                 if(jsoneq(js, t, "width") == 0 && indent<=1)\r
122                 {\r
123                         strcpy(js_sv, "width");//strdup(js+t->start);//, t->end - t->start);\r
124                 }else strcpy(js_sv, "\0");\r
125                 return 1;\r
126         } else if (t->type == JSMN_OBJECT) {\r
127                 //fprintf(stdout, "\n");\r
128                 j = 0;\r
129                 for (i = 0; i < t->size; i++) {\r
130                         //for (k = 0; k < indent; k++) fprintf(stdout, "\t");\r
131                         j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
132                         //fprintf(stdout, ": ");\r
133                         j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
134                         //fprintf(stdout, "\n");\r
135                 }\r
136                 return j+1;\r
137         } else if (t->type == JSMN_ARRAY) {\r
138                 j = 0;\r
139                 //fprintf(stdout, "==\n");\r
140                 for (i = 0; i < t->size; i++) {\r
141                         //for (k = 0; k < indent-1; k++) fprintf(stdout, "\t");\r
142                         //fprintf(stdout, "\t-");\r
143                         j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
144                         //fprintf(stdout, "==\n");\r
145                 }\r
146                 return j+1;\r
147         }\r
148         return 0;\r
149 }\r
150 \r
151 int loadmap(char *mn, map_t *map, global_game_variables_t *gvar)\r
152 {\r
153         int r;\r
154         static word incr=0;\r
155         int eof_expected = 0;\r
156         char *js = NULL;\r
157         size_t jslen = 0;\r
158         char buf[BUFSIZ];\r
159         static char js_ss[16];\r
160 \r
161         jsmn_parser p;\r
162         jsmntok_t *tok;\r
163         size_t tokcount = 2;\r
164 \r
165         FILE *fh = fopen(mn, "r");\r
166 \r
167         /* Prepare parser */\r
168         jsmn_init(&p);\r
169 \r
170         /* Allocate some tokens as a start */\r
171 //0000fprintf(stderr, "tok malloc\n");\r
172         tok = malloc(sizeof(*tok) * tokcount);\r
173         if (tok == NULL) {\r
174                 fprintf(stderr, "malloc(): errno=%d\n", errno);\r
175                 return 3;\r
176         }\r
177 \r
178         for (;;) {\r
179                 /* Read another chunk */\r
180 //0000fprintf(stderr, "read\n");\r
181                 r = fread(buf, 1, sizeof(buf), fh);\r
182                 if (r < 0) {\r
183                         fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);\r
184                         return 1;\r
185                 }\r
186                 if (r == 0) {\r
187                         if (eof_expected != 0) {\r
188                                 return 0;\r
189                         } else {\r
190                                 fprintf(stderr, "fread(): unexpected EOF\n");\r
191                                 return 2;\r
192                         }\r
193                 }\r
194 //0000fprintf(stdout, "r=       [%d]    BUFSIZ=%d\n", r, BUFSIZ);\r
195 //0000fprintf(stderr, "js alloc~\n");\r
196                 js = realloc(js, jslen + r + 1);\r
197                 if (js == NULL) {\r
198                         fprintf(stderr, "*js=%Fp\n", *js);\r
199                         fprintf(stderr, "realloc(): errno = %d\n", errno);\r
200                         return 3;\r
201                 }\r
202                 strncpy(js + jslen, buf, r);\r
203                 jslen = jslen + r;\r
204 \r
205 again:\r
206 //0000fprintf(stdout, " parse~ tok=%zu  jslen=%zu       r=%d    _memavl()=%u    BUFSIZ=%d~\n", tokcount, jslen, r, _memavl(), BUFSIZ);\r
207 //0000fprintf(stdout, "p=[%u]   [%u]    [%d]\n", p.pos, p.toknext, p.toksuper);\r
208 /*\r
209                 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
210 */\r
211                 r = jsmn_parse(&p, js, jslen, tok, tokcount);\r
212 //0000fprintf(stdout, "r=       [%d]\n", r);\r
213                 if (r < 0) {\r
214                         if (r == JSMN_ERROR_NOMEM) {\r
215                                 tokcount = tokcount * 2;\r
216 //0000fprintf(stderr, "tok realloc~ %zu\n", tokcount);\r
217                                 tok = realloc(tok, sizeof(*tok) * tokcount);\r
218                                 if (tok == NULL) {\r
219                                         fprintf(stderr, "realloc(): errno=%d\n", errno);\r
220                                         return 3;\r
221                                 }\r
222                                 goto again;\r
223                         }\r
224                 } else {\r
225                         //printf("js=%Fp\n", (js));\r
226                         //printf("*js=%Fp\n", (*(js)));\r
227                         //printf("&*js=%s\n", &(*(js)));\r
228                         //printf("&buf=[%Fp]\n", &buf);\r
229                         //printf("&buf_seg=[%x]\n", FP_SEG(&buf));\r
230                         //printf("&buf_off=[%x]\n", FP_OFF(&buf));\r
231                         //printf("&buf_fp=[%Fp]\n", MK_FP(FP_SEG(&buf), FP_OFF(&buf)));\r
232                         //printf("buf=[\n%s\n]\n", buf);\r
233                         //printf("buff=[%Fp]\n", buff);\r
234                         //printf("(*buff)=[%Fp]\n", (*buff));\r
235                         //printf("&(*buff)=[\n%s\n]\n", &(*buff));\r
236                         #ifdef DEBUG_DUMPVARS\r
237                         fprintf(stdout, "running dump~\n");\r
238                         #endif\r
239                         dump(js, tok, p.toknext, incr, &js_ss, map, 0);\r
240                         eof_expected = 1;\r
241                 }\r
242         }\r
243 \r
244         //free(js);\r
245         //free(tok);\r
246         //fclose(fh);\r
247 \r
248         return 0;\r
249 }\r
250 \r
251 void extract_map(const char *js, jsmntok_t *t, size_t count, map_t *map) {\r
252         int i, j, k, indent=0, inner_end;\r
253         //bitmap_t bp;\r
254 \r
255         i = 0;\r
256         while(i<count) {\r
257                 if(jsoneq(js, &(t[i]), "layers") == 0) {\r
258                         i++;\r
259                         map->layerdata = malloc(sizeof(byte*) * t[i].size);\r
260                         inner_end = t[i].end;\r
261                         k = 0;\r
262                         while(t[i].start < inner_end) {\r
263 #ifdef DEBUG_DUMPVARS\r
264                                 printf("t[%d].start=%d, %d\n", i, t[i].start, inner_end);\r
265 #endif\r
266                                 if(jsoneq(js, &(t[i]), "data") == 0) {\r
267 #ifdef DEBUG_MAPDATA\r
268                                         printf("Layer %d data: [\n", k);\r
269 #endif\r
270                                         map->layerdata[k] = malloc(sizeof(byte) * t[i+1].size);\r
271                                         map->data = map->layerdata[k];\r
272                                         for(j = 0; j < t[i+1].size; j++) {\r
273                                                 map->layerdata[k][j] = (byte)atoi(js + t[i+2+j].start);\r
274                                                 //for backwards compatibility for rest of code\r
275 //                                              map->data[j] = map->layerdata[k][j];//(byte)atoi(js + t[i+2+j].start);//(byte)atoi(js+t->start);\r
276 #ifdef DEBUG_MAPDATA\r
277                                                 //printf("[%d,%d]%d", k, j, map->layerdata[k][j]);\r
278                                                 fprintf(stdout, "%c", map->data[j]+44);\r
279 #endif\r
280                                         }\r
281                                         i += j + 2;\r
282                                         k++;\r
283 #ifdef DEBUG_MAPDATA\r
284                                         puts("\n]");\r
285 #endif\r
286                                 }else{\r
287                                         i++;\r
288                                 }\r
289                         }\r
290                 }\r
291                 if(jsoneq(js, &(t[i]), "tilesets") == 0) {\r
292                         i++;\r
293                         map->tiles = malloc(sizeof(tiles_t*) * t[i].size);\r
294                         inner_end = t[i].end;\r
295                         k = 0;\r
296                         while(t[i].start < inner_end) {\r
297                                 if(jsoneq(js, &(t[i]), "image") == 0) {\r
298                                         map->layertile[k] = malloc(sizeof(tiles_t));\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                                         map->layertile[k]->btdata = malloc(sizeof(bitmap_t));\r
304                                         map->layertile[k]->tileHeight = 16;\r
305                                         map->layertile[k]->tileWidth = 16;\r
306                                         map->layertile[k]->rows = 1;\r
307                                         map->layertile[k]->cols = 1;\r
308 #ifdef __DEBUG_MAP__\r
309                                         dbg_maptext=false;\r
310 #endif\r
311                                         map->tiles->btdata = map->layertile[k]->btdata;\r
312                                         map->tiles->tileHeight = 16;\r
313                                         map->tiles->tileWidth = 16;\r
314                                         map->tiles->rows = 1;\r
315                                         map->tiles->cols = 1;\r
316                                         k++;\r
317                                 }\r
318                                 i++;\r
319                         }\r
320                 }\r
321 \r
322                 if (jsoneq(js, &(t[i]), "height") == 0 && indent<=1) {\r
323                         map->height = atoi(js + t[i+1].start);\r
324 #ifdef DEBUG_MAPVAR\r
325                         printf("Height: %d\n", map->height);\r
326 #endif\r
327                         i++;\r
328                 }\r
329                 else if(jsoneq(js, &(t[i]), "width") == 0 && indent<=1) {\r
330                         map->width = atoi(js + t[i+1].start);\r
331 #ifdef DEBUG_MAPVAR\r
332                         printf("Width: %d\n", map->width);\r
333 #endif\r
334                         i++;\r
335                 }\r
336                 i++;\r
337         }\r
338 }\r
339 \r
340 int newloadmap(char *mn, map_t *map) {\r
341         char *js;\r
342 \r
343         jsmn_parser p;\r
344         jsmntok_t *tok = NULL;\r
345         size_t tokcount, file_s;\r
346 \r
347         FILE *fh = fopen(mn, "r");\r
348         int status;\r
349 \r
350         /* Prepare parser */\r
351         jsmn_init(&p);\r
352 \r
353         file_s = filesize(fh);\r
354         js = malloc(file_s);\r
355         if(js == NULL) {\r
356                 fprintf(stderr, "malloc(): errno = %d", 2);\r
357                 fclose(fh);\r
358                 return 3;\r
359         }\r
360         if(fread(js, 1, file_s, fh) != file_s) {\r
361                 fprintf(stderr, "Map read error");\r
362                 free(js);\r
363                 fclose(fh);\r
364                 return 1;\r
365         }\r
366         tokcount = jsmn_parse(&p, js, file_s, NULL, 0);\r
367         tok = malloc(tokcount*sizeof(jsmntok_t));\r
368         printf("Allocated %d tokens", tokcount);\r
369         jsmn_init(&p);\r
370         if((status = jsmn_parse(&p, js, file_s, tok, tokcount)) < 0)\r
371         {\r
372                 printf("Error: %d\n", status);\r
373                 return status;\r
374         }\r
375         else if(status != tokcount) { printf("Warning: used %d tok\n", status);}\r
376         extract_map(js, tok, tokcount, map);\r
377 \r
378         free(js);\r
379         free(tok);\r
380         fclose(fh);\r
381 \r
382         return 0;\r
383 }\r
384 \r
385 \r
386 //======\r
387 \r
388 \r
389 #define MAPBUFINLM (gvar->ca.camap.mapsegs)\r
390 int CA_loadmap(char *mn, map_t *map, global_game_variables_t *gvar)\r
391 {\r
392         jsmn_parser p;\r
393         jsmntok_t *tok = NULL;\r
394         size_t tokcount, file_s;\r
395 \r
396         FILE *fh = fopen(mn, "r");\r
397         int status;\r
398 \r
399         /* Prepare parser */\r
400         jsmn_init(&p);\r
401 \r
402         file_s = filesize(fh);\r
403         CA_LoadFile(mn, &MAPBUFINLM, gvar);\r
404         tokcount = jsmn_parse(&p, MAPBUFINLM, file_s, NULL, 0);\r
405         tok = malloc(tokcount*sizeof(jsmntok_t));\r
406 //      printf("Allocated %d tokens", tokcount);\r
407         jsmn_init(&p);\r
408         if((status = jsmn_parse(&p, MAPBUFINLM, file_s, tok, tokcount)) < 0)\r
409         {\r
410                 printf("Error: %d\n", status);\r
411                 return status;\r
412         }\r
413         else if(status != tokcount) { printf("Warning: used %d tok\n", status);}\r
414         extract_map(MAPBUFINLM, tok, tokcount, map);\r
415 \r
416         free(tok);\r
417         fclose(fh);\r
418 \r
419         return 0;\r
420 }\r