@@ -2194,18 +2194,11 @@ void plotvalue (char **statement)
21942194
21952195}
21962196
2197-
21982197void plotmapfile (char * * statement )
21992198{
22002199 // 1 2 3 4 5 6 7
22012200 // plotmapfile map_file.tmx display_mem screen_x screen_y screen_width screen_height
22022201
2203- // Overview
2204- // 1. open map file
2205- // 2. create an int array of widthxheight
2206- // 3. set each cell of the int according to the palette of the character there
2207- // 4. run through the array and build up the data structure for plotcharloop
2208-
22092202 char datavalues [256 ][256 ];
22102203 int s , t ;
22112204 int x , y , width , height ;
@@ -2224,30 +2217,57 @@ void plotmapfile (char **statement)
22242217
22252218 fixfilename (statement [2 ]);
22262219
2227- //open file...
2228- FILE * fp = fopen (statement [2 ], "rb" );
2220+ FILE * fp = fopen (statement [2 ], "rb" );
22292221 if (!fp )
2230- {
2231- prerror ("plotmapfile couldn't open map file '%s' for reading" , statement [2 ]);
2232- }
2222+ prerror ("plotmapfile couldn't open map file '%s' for reading" , statement [2 ]);
2223+
2224+ // 1. Get file size and read entire file into memory
2225+ fseek (fp , 0 , SEEK_END );
2226+ long file_size = ftell (fp );
2227+ rewind (fp );
2228+
2229+ char * file_buffer = malloc (file_size + 1 );
2230+ if (file_buffer == NULL )
2231+ prerror ("couldn't allocate memory to read %s" , statement [2 ]);
22332232
2233+ if (fread (file_buffer , 1 , file_size , fp ) != file_size )
2234+ prerror ("couldn't read %s into memory" , statement [2 ]);
2235+ fclose (fp );
2236+ file_buffer [file_size ] = '\0' ; // Null-terminate the entire buffer
22342237
22352238 //our default data label...
22362239 for (t = 0 ; t < 256 ; t ++ )
22372240 sprintf (datavalues [t ], "palette0" );
2238- //datavalues
2239- for (;;)
2241+
2242+ // 2. Process the file from the in-memory buffer
2243+ char * current_pos = file_buffer ;
2244+ char * buffer_end = file_buffer + file_size ;
2245+
2246+ while (current_pos < buffer_end )
22402247 {
2241- char line [1024 ];
2248+ char line [1024 ];
2249+ char * line_end = strchr (current_pos , '\n' );
2250+ long line_len ;
2251+
2252+ if (line_end ) {
2253+ line_len = line_end - current_pos ;
2254+ } else {
2255+ line_len = buffer_end - current_pos ;
2256+ }
2257+
2258+ if (line_len >= sizeof (line )) {
2259+ prerror ("line too long in map file '%s'" , statement [2 ]);
2260+ }
2261+
2262+ memcpy (line , current_pos , line_len );
2263+ line [line_len ] = '\0' ;
2264+
22422265 char * keyword ;
22432266 char * firstgid ;
22442267 char * tilename ;
22452268 int gid ;
22462269 int layer = 0 ;
22472270
2248- if (fgets (line , 1024 , fp ) == NULL )
2249- break ;
2250-
22512271 keyword = strstr (line , "tileset firstgid=\"" );
22522272 if (keyword != NULL )
22532273 {
@@ -2292,26 +2312,29 @@ void plotmapfile (char **statement)
22922312 {
22932313 if ((q == 999 ) || (palettefilenames [q ][0 ] == 0 ))
22942314 {
2295- if (passes == 0 )
2296- return ;
2297- else
2298- prerror ("plotmapfile didn't find a palette for %s" , datavalues [gid ]);
2315+ if (passes == 0 ) {
2316+ // Can't error on first pass, just exit loop and function
2317+ current_pos = buffer_end ;
2318+ break ;
2319+ }
2320+ prerror ("plotmapfile didn't find a palette for %s" , datavalues [gid ]);
22992321 }
23002322
23012323 if (strcmp (palettefilenames [q ], datavalues [gid ]) == 0 )
23022324 break ;
23032325 }
2304-
2305- palettevalues [tileindex ] = graphicfilepalettes [q ];
2306- graphicmodes [tileindex ] = graphicfilemodes [q ];
2326+ if (q < 1000 && palettefilenames [q ][0 ] != 0 ) {
2327+ palettevalues [tileindex ] = graphicfilepalettes [q ];
2328+ graphicmodes [tileindex ] = graphicfilemodes [q ];
2329+ }
23072330
23082331 tileindex ++ ;
23092332 }
23102333
23112334 keyword = strstr (line , "<data encoding=\"" );
23122335 if (keyword != NULL )
23132336 {
2314- fclose ( fp );
2337+ free ( file_buffer );
23152338 keyword = keyword + 15 ;
23162339 for (t = 0 ; t < 1024 ; t ++ )
23172340 if (line [t ] == '"' )
@@ -2324,13 +2347,23 @@ void plotmapfile (char **statement)
23242347 layer = layer + 1 ;
23252348 if (layer > 1 )
23262349 {
2327- fclose ( fp );
2350+ free ( file_buffer );
23282351 prerror ("map file '%s' contains multiple layers" , statement [2 ]);
23292352 }
23302353 }
2354+
2355+ if (line_end ) {
2356+ current_pos = line_end + 1 ;
2357+ } else {
2358+ break ; // End of buffer
2359+ }
23312360 }
2332- fclose ( fp );
2361+ free ( file_buffer );
23332362
2363+ // If we bailed on pass 0, just return now.
2364+ if (passes == 0 && (tileindex == 0 || (palettevalues [0 ] == 0 && tileindex < 2 ))) {
2365+ return ;
2366+ }
23342367
23352368 int startp ;
23362369 int pmwidth , charwidth , pmx , pmy , pmemoffset , pmwidthandpalette ;
@@ -2397,6 +2430,7 @@ void plotmapfile (char **statement)
23972430 templabel = templabel + 1 ;
23982431}
23992432
2433+
24002434void plotmap (char * * statement )
24012435{
24022436
@@ -3623,80 +3657,115 @@ void incmapfile (char **statement)
36233657
36243658 backupthisfile (statement [2 ]);
36253659
3626- //open file...
3627- FILE * fp = fopen (statement [2 ], "rb" );
3660+ FILE * fp = fopen (statement [2 ], "rb" );
36283661 if (!fp )
3629- {
3630- prerror ("incmapfile couldn't open map file '%s' for reading" , statement [2 ]);
3631- }
3662+ prerror ("incmapfile couldn't open map file '%s' for reading" , statement [2 ]);
36323663
3633- for (;;)
3664+ // 1. Get file size and read entire file into memory
3665+ fseek (fp , 0 , SEEK_END );
3666+ long file_size = ftell (fp );
3667+ rewind (fp );
3668+
3669+ char * file_buffer = malloc (file_size + 1 );
3670+ if (file_buffer == NULL )
3671+ prerror ("couldn't allocate memory to read %s" , statement [2 ]);
3672+
3673+ if (fread (file_buffer , 1 , file_size , fp ) != file_size )
3674+ prerror ("couldn't read %s into memory" , statement [2 ]);
3675+ fclose (fp );
3676+ file_buffer [file_size ] = '\0' ; // Null-terminate the entire buffer
3677+
3678+ // 2. Process the file from the in-memory buffer
3679+ char * current_pos = file_buffer ;
3680+ char * buffer_end = file_buffer + file_size ;
3681+
3682+ while (current_pos < buffer_end )
36343683 {
3635- char line [1024 ];
3636- char * keyword ;
3637- char * firstgid ;
3638- char * tilename ;
3639- int gid ;
3640- int layer = 0 ;
3684+ char line [1024 ];
3685+ char * line_end = strchr (current_pos , '\n' );
3686+ long line_len ;
36413687
3642- if (fgets (line , 1024 , fp ) == NULL )
3643- break ;
3688+ if (line_end ) {
3689+ line_len = line_end - current_pos ;
3690+ } else {
3691+ line_len = buffer_end - current_pos ;
3692+ }
36443693
3645- keyword = strstr (line , "tileset firstgid=\"" );
3646- if (keyword != NULL )
3647- {
3648- firstgid = strstr (line , "firstgid=\"" );
3649- tilename = strstr (line , "name=\"" );
3650- if ((tilename != NULL ) && (firstgid != NULL ))
3651- {
3652- gid = atoi (firstgid + 10 );
3653- tilename = tilename + 6 ;
3654- for (t = 0 ; t < 1024 ; t ++ )
3655- if (line [t ] == '"' )
3656- line [t ] = 0 ;
3657- s = 0 ;
3658- for (t = gid ; t < 256 ; t ++ )
3659- {
3660- sprintf (datavalues [t ], " .byte <(%s+%d)\n" , tilename , s );
3661- s = s + 1 ;
3662- if (doublewide == 1 )
3663- s = s + 1 ;
3664- }
3665- }
3666- }
3694+ if (line_len >= sizeof (line )) {
3695+ prerror ("line too long in map file '%s'" , statement [2 ]);
3696+ }
3697+
3698+ memcpy (line , current_pos , line_len );
3699+ line [line_len ] = '\0' ;
3700+
3701+ char * keyword ;
3702+ char * firstgid ;
3703+ char * tilename ;
3704+ int gid ;
3705+ int layer = 0 ;
3706+
3707+ keyword = strstr (line , "tileset firstgid=\"" );
3708+ if (keyword != NULL )
3709+ {
3710+ firstgid = strstr (line , "firstgid=\"" );
3711+ tilename = strstr (line , "name=\"" );
3712+ if ((tilename != NULL ) && (firstgid != NULL ))
3713+ {
3714+ gid = atoi (firstgid + 10 );
3715+ tilename = tilename + 6 ;
3716+ for (t = 0 ; t < 1024 ; t ++ )
3717+ if (line [t ] == '"' )
3718+ line [t ] = 0 ;
3719+ s = 0 ;
3720+ for (t = gid ; t < 256 ; t ++ )
3721+ {
3722+ sprintf (datavalues [t ], " .byte <(%s+%d)\n" , tilename , s );
3723+ s = s + 1 ;
3724+ if (doublewide == 1 )
3725+ s = s + 1 ;
3726+ }
3727+ }
3728+ }
36673729
3668- keyword = strstr (line , "tile gid=\"" );
3669- if (keyword != NULL )
3670- {
3671- gid = atoi (keyword + 10 );
3672- if (!thisdatabankset )
3673- printf ("%s" , datavalues [gid ]);
3674- else
3675- gfxprintf ("%s" , datavalues [gid ]);
3676- }
3730+ keyword = strstr (line , "tile gid=\"" );
3731+ if (keyword != NULL )
3732+ {
3733+ gid = atoi (keyword + 10 );
3734+ if (!thisdatabankset )
3735+ printf ("%s" , datavalues [gid ]);
3736+ else
3737+ gfxprintf ("%s" , datavalues [gid ]);
3738+ }
36773739
3678- keyword = strstr (line , "<data encoding=\"" );
3679- if (keyword != NULL )
3680- {
3681- fclose (fp );
3682- keyword = keyword + 15 ;
3683- for (t = 0 ; t < 1024 ; t ++ )
3684- if (line [t ] == '"' )
3685- line [t ] = 0 ;
3686- prerror ("map file '%s' is %s encoded. XML is required" , statement [2 ], keyword );
3687- }
3688- keyword = strstr (line , "<layer name=\"" );
3689- if (keyword != NULL )
3690- {
3691- layer = layer + 1 ;
3692- if (layer > 1 )
3693- {
3694- fclose (fp );
3695- prerror ("map file '%s' contains multiple layers" , statement [2 ]);
3696- }
3697- }
3740+ keyword = strstr (line , "<data encoding=\"" );
3741+ if (keyword != NULL )
3742+ {
3743+ free (file_buffer );
3744+ keyword = keyword + 15 ;
3745+ for (t = 0 ; t < 1024 ; t ++ )
3746+ if (line [t ] == '"' )
3747+ line [t ] = 0 ;
3748+ prerror ("map file '%s' is %s encoded. XML is required" , statement [2 ], keyword );
3749+ }
3750+ keyword = strstr (line , "<layer name=\"" );
3751+ if (keyword != NULL )
3752+ {
3753+ layer = layer + 1 ;
3754+ if (layer > 1 )
3755+ {
3756+ free (file_buffer );
3757+ prerror ("map file '%s' contains multiple layers" , statement [2 ]);
3758+ }
3759+ }
3760+
3761+ if (line_end ) {
3762+ current_pos = line_end + 1 ;
3763+ } else {
3764+ break ; // End of buffer
3765+ }
36983766 }
3699- fclose (fp );
3767+
3768+ free (file_buffer );
37003769
37013770 if (!thisdatabankset )
37023771 printf ("skipmapdata%d\n" , templabel );
0 commit comments