| 
									
										
										
										
											2007-11-17 02:25:45 +08:00
										 |  |  | /* ASE - Allegro Sprite Editor
 | 
					
						
							| 
									
										
										
										
											2010-02-02 05:25:40 +08:00
										 |  |  |  * Copyright (C) 2001-2010  David Capello | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation; either version 2 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "config.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <allegro/color.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "file/file.h"
 | 
					
						
							| 
									
										
										
										
											2008-02-12 20:46:39 +08:00
										 |  |  | #include "file/fli/fli.h"
 | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  | #include "modules/palettes.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | #include "raster/raster.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | static bool load_FLI(FileOp *fop); | 
					
						
							|  |  |  | static bool save_FLI(FileOp *fop); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int get_time_precision(Sprite *sprite); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-05 09:30:50 +08:00
										 |  |  | FileFormat format_fli = | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   "flc", | 
					
						
							|  |  |  |   "flc,fli", | 
					
						
							|  |  |  |   load_FLI, | 
					
						
							|  |  |  |   save_FLI, | 
					
						
							| 
									
										
										
										
											2008-03-29 11:43:19 +08:00
										 |  |  |   NULL, | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   FILE_SUPPORT_INDEXED | | 
					
						
							|  |  |  |   FILE_SUPPORT_FRAMES | | 
					
						
							|  |  |  |   FILE_SUPPORT_PALETTES | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* loads a FLI/FLC file */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | static bool load_FLI(FileOp *fop) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  | #define SETPAL()						\
 | 
					
						
							|  |  |  |   do {								\ | 
					
						
							|  |  |  |       for (c=0; c<256; c++) {					\ | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  | 	pal->setEntry(c, _rgba(cmap[c*3],			\ | 
					
						
							|  |  |  | 			       cmap[c*3+1],			\ | 
					
						
							|  |  |  | 			       cmap[c*3+2], 255));		\ | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |       }								\ | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |       pal->setFrame(frpos_out);					\ | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       sprite->setPalette(pal, true);				\ | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   unsigned char cmap[768]; | 
					
						
							|  |  |  |   unsigned char omap[768]; | 
					
						
							|  |  |  |   s_fli_header fli_header; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   Image *bmp, *old, *image; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   Sprite *sprite; | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |   LayerImage *layer; | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   Palette *pal; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   int c, w, h; | 
					
						
							|  |  |  |   int frpos_in; | 
					
						
							|  |  |  |   int frpos_out; | 
					
						
							|  |  |  |   int index = 0; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   Cel *cel; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   FILE *f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* open the file to read in binary mode */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   f = fopen(fop->filename, "rb"); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   if (!f) | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |   fli_read_header(f, &fli_header); | 
					
						
							|  |  |  |   fseek(f, 128, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   if (fli_header.magic == NO_HEADER) { | 
					
						
							| 
									
										
										
										
											2010-09-19 10:54:56 +08:00
										 |  |  |     fop_error(fop, "The file doesn't have a FLIC header\n"); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |     fclose(f); | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   /* size by frame */ | 
					
						
							|  |  |  |   w = fli_header.width; | 
					
						
							|  |  |  |   h = fli_header.height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* create the bitmaps */ | 
					
						
							| 
									
										
										
										
											2007-09-20 08:32:35 +08:00
										 |  |  |   bmp = image_new(IMAGE_INDEXED, w, h); | 
					
						
							|  |  |  |   old = image_new(IMAGE_INDEXED, w, h); | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |   pal = new Palette(0, 256); | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   if (!bmp || !old || !pal) { | 
					
						
							| 
									
										
										
										
											2010-09-19 10:54:56 +08:00
										 |  |  |     fop_error(fop, "Not enough memory.\n"); | 
					
						
							| 
									
										
										
										
											2007-09-20 08:32:35 +08:00
										 |  |  |     if (bmp) image_free(bmp); | 
					
						
							|  |  |  |     if (old) image_free(old); | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |     if (pal) delete pal; | 
					
						
							| 
									
										
										
										
											2007-09-20 08:32:35 +08:00
										 |  |  |     fclose(f); | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   // Create the image
 | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |   sprite = new Sprite(IMAGE_INDEXED, w, h, 256); | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |   layer = new LayerImage(sprite); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   sprite->getFolder()->add_layer(layer); | 
					
						
							| 
									
										
										
										
											2010-09-19 11:17:21 +08:00
										 |  |  |   layer->configureAsBackground(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   // Set frames and speed
 | 
					
						
							|  |  |  |   sprite->setTotalFrames(fli_header.frames); | 
					
						
							|  |  |  |   sprite->setDurationForAllFrames(fli_header.speed); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* write frame by frame */ | 
					
						
							|  |  |  |   for (frpos_in=frpos_out=0; | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |        frpos_in<sprite->getTotalFrames(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |        frpos_in++) { | 
					
						
							|  |  |  |     /* read the frame */ | 
					
						
							|  |  |  |     fli_read_frame(f, &fli_header, | 
					
						
							|  |  |  | 		   (unsigned char *)old->dat, omap, | 
					
						
							|  |  |  | 		   (unsigned char *)bmp->dat, cmap); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |     /* first frame, or the frames changes, or the palette changes */ | 
					
						
							|  |  |  |     if ((frpos_in == 0) || | 
					
						
							|  |  |  | 	(image_count_diff(old, bmp)) | 
					
						
							|  |  |  | #ifndef USE_LINK /* TODO this should be configurable through a check-box */
 | 
					
						
							|  |  |  | 	|| (memcmp(omap, cmap, 768) != 0) | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       /* the image changes? */ | 
					
						
							|  |  |  |       if (frpos_in != 0) | 
					
						
							|  |  |  | 	frpos_out++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* add the new frame */ | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |       image = image_new_copy(bmp); | 
					
						
							|  |  |  |       if (!image) { | 
					
						
							| 
									
										
										
										
											2010-09-19 10:54:56 +08:00
										 |  |  | 	fop_error(fop, "Not enough memory\n"); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 	break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       index = stock_add_image(sprite->getStock(), image); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |       if (index < 0) { | 
					
						
							|  |  |  | 	image_free(image); | 
					
						
							| 
									
										
										
										
											2010-09-19 10:54:56 +08:00
										 |  |  | 	fop_error(fop, "Not enough memory\n"); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 	break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cel = cel_new(frpos_out, index); | 
					
						
							|  |  |  |       if (!cel) { | 
					
						
							| 
									
										
										
										
											2010-09-19 10:54:56 +08:00
										 |  |  | 	fop_error(fop, "Not enough memory\n"); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | 	break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  |       layer->add_cel(cel); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* first frame or the palette changes */ | 
					
						
							|  |  |  |       if ((frpos_in == 0) || (memcmp(omap, cmap, 768) != 0)) | 
					
						
							|  |  |  | 	SETPAL(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | #ifdef USE_LINK
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     /* the palette changes */ | 
					
						
							|  |  |  |     else if (memcmp(omap, cmap, 768) != 0) { | 
					
						
							|  |  |  |       frpos_out++; | 
					
						
							|  |  |  |       SETPAL(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* add link */ | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |       cel = cel_new(frpos_out, index); | 
					
						
							|  |  |  |       if (!cel) { | 
					
						
							|  |  |  | 	fop_error(fop, _("Not enough memory\n")); | 
					
						
							|  |  |  | 	break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       layer_add_cel(layer, cel); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     // The palette and the image don't change: add duration to the last added frame
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       sprite->setFrameDuration(frpos_out, | 
					
						
							|  |  |  | 			       sprite->getFrameDuration(frpos_out)+fli_header.speed); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* update the old image and color-map to the new ones to compare later */ | 
					
						
							|  |  |  |     image_copy(old, bmp, 0, 0); | 
					
						
							|  |  |  |     memcpy(omap, cmap, 768); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* update progress */ | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     fop_progress(fop, (float)(frpos_in+1) / (float)(sprite->getTotalFrames())); | 
					
						
							| 
									
										
										
										
											2008-02-11 03:06:03 +08:00
										 |  |  |     if (fop_is_stop(fop)) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* just one frame? */ | 
					
						
							|  |  |  |     if (fop->oneframe) | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   // Update number of frames
 | 
					
						
							|  |  |  |   sprite->setTotalFrames(frpos_out+1); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   // Close the file
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   fclose(f); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   // Destroy the bitmaps
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   image_free(bmp); | 
					
						
							|  |  |  |   image_free(old); | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |   delete pal; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   fop->sprite = sprite; | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* saves a FLC file */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  | static bool save_FLI(FileOp *fop) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   Sprite *sprite = fop->sprite; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   unsigned char cmap[768]; | 
					
						
							|  |  |  |   unsigned char omap[768]; | 
					
						
							|  |  |  |   s_fli_header fli_header; | 
					
						
							|  |  |  |   int c, frpos, times; | 
					
						
							|  |  |  |   Image *bmp, *old; | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  |   Palette *pal; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   FILE *f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* prepare fli header */ | 
					
						
							|  |  |  |   fli_header.filesize = 0; | 
					
						
							|  |  |  |   fli_header.frames = 0; | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   fli_header.width = sprite->getWidth(); | 
					
						
							|  |  |  |   fli_header.height = sprite->getHeight(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ((fli_header.width == 320) && (fli_header.height == 200)) | 
					
						
							|  |  |  |     fli_header.magic = HEADER_FLI; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     fli_header.magic = HEADER_FLC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   fli_header.depth = 8; | 
					
						
							|  |  |  |   fli_header.flags = 3; | 
					
						
							|  |  |  |   fli_header.speed = get_time_precision(sprite); | 
					
						
							|  |  |  |   fli_header.created = 0; | 
					
						
							|  |  |  |   fli_header.updated = 0; | 
					
						
							|  |  |  |   fli_header.aspect_x = 1; | 
					
						
							|  |  |  |   fli_header.aspect_y = 1; | 
					
						
							|  |  |  |   fli_header.oframe1 = fli_header.oframe2 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* open the file to write in binary mode */ | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   f = fopen(fop->filename, "wb"); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   if (!f) | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |   fseek(f, 128, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* create the bitmaps */ | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   bmp = image_new(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight()); | 
					
						
							|  |  |  |   old = image_new(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight()); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   if ((!bmp) || (!old)) { | 
					
						
							| 
									
										
										
										
											2010-09-19 10:54:56 +08:00
										 |  |  |     fop_error(fop, "Not enough memory for temporary bitmaps.\n"); | 
					
						
							| 
									
										
										
										
											2008-01-07 23:10:17 +08:00
										 |  |  |     if (bmp) image_free(bmp); | 
					
						
							|  |  |  |     if (old) image_free(old); | 
					
						
							|  |  |  |     fclose(f); | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* write frame by frame */ | 
					
						
							|  |  |  |   for (frpos=0; | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |        frpos<sprite->getTotalFrames(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |        frpos++) { | 
					
						
							|  |  |  |     /* get color map */ | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     pal = sprite->getPalette(frpos); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     for (c=0; c<256; c++) { | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |       cmap[3*c  ] = _rgba_getr(pal->getEntry(c)); | 
					
						
							|  |  |  |       cmap[3*c+1] = _rgba_getg(pal->getEntry(c)); | 
					
						
							|  |  |  |       cmap[3*c+2] = _rgba_getb(pal->getEntry(c)); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* render the frame in the bitmap */ | 
					
						
							|  |  |  |     image_clear(bmp, 0); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     layer_render(sprite->getFolder(), bmp, 0, 0, frpos); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* how many times this frame should be written to get the same
 | 
					
						
							|  |  |  |        time that it has in the sprite */ | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     times = sprite->getFrameDuration(frpos) / fli_header.speed; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (c=0; c<times; c++) { | 
					
						
							|  |  |  |       /* write this frame */ | 
					
						
							|  |  |  |       if (frpos == 0 && c == 0) | 
					
						
							|  |  |  | 	fli_write_frame(f, &fli_header, NULL, NULL, | 
					
						
							|  |  |  | 			(unsigned char *)bmp->dat, cmap, W_ALL); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	fli_write_frame(f, &fli_header, | 
					
						
							|  |  |  | 			(unsigned char *)old->dat, omap, | 
					
						
							|  |  |  | 			(unsigned char *)bmp->dat, cmap, W_ALL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* update the old image and color-map to the new ones to compare later */ | 
					
						
							|  |  |  |       image_copy(old, bmp, 0, 0); | 
					
						
							|  |  |  |       memcpy(omap, cmap, 768); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* update progress */ | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     fop_progress(fop, (float)(frpos+1) / (float)(sprite->getTotalFrames())); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* write the header and close the file */ | 
					
						
							|  |  |  |   fli_write_header(f, &fli_header); | 
					
						
							|  |  |  |   fclose(f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* destroy the bitmaps */ | 
					
						
							|  |  |  |   image_free(bmp); | 
					
						
							|  |  |  |   image_free(old); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-31 00:43:13 +08:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int get_time_precision(Sprite *sprite) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int precision = 1000; | 
					
						
							|  |  |  |   int c, len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   for (c = 0; c < sprite->getTotalFrames() && precision > 1; c++) { | 
					
						
							|  |  |  |     len = sprite->getFrameDuration(c); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     while (len / precision == 0) | 
					
						
							|  |  |  |       precision /= 10; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return precision; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |