]> 4ch.mooo.com Git - 16.git/blob - 16_map.c
895e4d68345a24e7f8301fa5e336ae9280f3798a
[16.git] / 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 #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)\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         //char *s;\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                                 printf("%d, %d\n", t[i].start, inner_end);\r
264                                 if(jsoneq(js, &(t[i]), "data") == 0) {\r
265                                         #ifdef DEBUG_MAPVAR\r
266                                         printf("Layer %d data: [", k);\r
267                                         #endif\r
268                                         map->layerdata[k] = malloc(sizeof(byte) * t[i+1].size);\r
269                                         for(j = 0; j < t[i+1].size; j++) {\r
270                                                 map->layerdata[k][j] = (byte)atoi(js + t[i+2+j].start);\r
271                                                 #ifdef DEBUG_MAPVAR\r
272                                                 printf("%d, ", map->layerdata[k][j]);\r
273                                                 #endif\r
274                                         }\r
275                                         i += j + 2;\r
276                                         k++;\r
277                                         #ifdef DEBUG_MAPVAR\r
278                                         puts("]");\r
279                                         #endif\r
280                                 }\r
281                                 else{\r
282                                         i++;\r
283                                 }\r
284                         }\r
285                 }\r
286                 if(jsoneq(js, &(t[i]), "tilesets") == 0) {\r
287                         i++;\r
288                         map->tiles = malloc(sizeof(tiles_t*) * t[i].size);\r
289                         inner_end = t[i].end;\r
290                         k = 0;\r
291                         while(t[i].start < inner_end) {\r
292                                 if(jsoneq(js, &(t[i]), "image") == 0) {\r
293                                         //fix this to be far~\r
294                                         map->layertile[k] = malloc(sizeof(tiles_t));\r
295                                         map->layertile[k]->btdata = malloc(sizeof(bitmap_t));\r
296                                         map->layertile[k]->tileHeight = 16;\r
297                                         map->layertile[k]->tileWidth = 16;\r
298                                         map->layertile[k]->rows = 1;\r
299                                         map->layertile[k]->cols = 1;\r
300 #ifdef __DEBUG_MAP__\r
301                                         dbg_maptext=false;\r
302 #endif\r
303                                         //Fix to load tileset specified.\r
304                                         //And move to vrs, probably\r
305                                         //bp = bitmapLoadPcx("data/ed.pcx");\r
306                                         map->layertile[k]->btdata = &bp;\r
307                                         k++;\r
308                                 }\r
309                                 i++;\r
310                         }\r
311                 }\r
312 \r
313                 if (jsoneq(js, &(t[i]), "height") == 0 && indent<=1) {\r
314                         map->height = atoi(js + t[i+1].start);\r
315                         #ifdef DEBUG_MAPVAR\r
316                         printf("Height: %d\n", map->height);\r
317                         #endif\r
318                         i++;\r
319                 }\r
320                 else if(jsoneq(js, &(t[i]), "width") == 0 && indent<=1) {\r
321                         map->width = atoi(js + t[i+1].start);\r
322                         #ifdef DEBUG_MAPVAR\r
323                         printf("Width: %d\n", map->width);\r
324                         #endif\r
325                         i++;\r
326                 }\r
327                 i++;\r
328         }\r
329 }\r
330 \r
331 int newloadmap(char *mn, map_t *map) {\r
332         char *js;\r
333 \r
334         jsmn_parser p;\r
335         jsmntok_t *tok = NULL;\r
336         size_t tokcount, file_s;\r
337 \r
338         FILE *fh = fopen(mn, "r");\r
339         int status;\r
340 \r
341         /* Prepare parser */\r
342         jsmn_init(&p);\r
343 \r
344         file_s = filesize(fh);\r
345         js = malloc(file_s);\r
346         if(js == NULL) {\r
347                 fprintf(stderr, "malloc(): errno = %d", 2);\r
348                 fclose(fh);\r
349                 return 3;\r
350         }\r
351         if(fread(js, 1, file_s, fh) != file_s) {\r
352                 fprintf(stderr, "Map read error");\r
353                 free(js);\r
354                 fclose(fh);\r
355                 return 1;\r
356         }\r
357         tokcount = jsmn_parse(&p, js, file_s, NULL, 0);\r
358         tok = malloc(tokcount*sizeof(jsmntok_t));\r
359         printf("Allocated %d tokens", tokcount);\r
360         jsmn_init(&p);\r
361         if((status = jsmn_parse(&p, js, file_s, tok, tokcount)) < 0)\r
362         {\r
363                 printf("Error: %d\n", status);\r
364                 return status;\r
365         }\r
366         else if(status != tokcount) { printf("Warning: used %d tok\n", status);}\r
367         extract_map(js, tok, tokcount, map);\r
368 \r
369         free(js);\r
370         free(tok);\r
371         fclose(fh);\r
372 \r
373         return 0;\r
374 }\r