2 * $Logfile: /Freespace2/code/Anim/PackUnpack.cpp $
7 * Code for handling packing and unpacking in Hoffoss's RLE format, used for
8 * Anim files. Also handles Anim loading, creating Anim instances (for
9 * utilizing an Anim), and getting getting frames of the Anim.
12 * Revision 1.1 2002/05/03 03:28:08 root
16 * 12 7/30/99 10:10p Dave
17 * Fixed loading bar in 32 bit mode.
19 * 11 7/18/99 1:59p Johnson
20 * Fixed potential anim locking problem.
22 * 10 7/16/99 1:49p Dave
23 * 8 bit aabitmaps. yay.
25 * 9 7/13/99 1:15p Dave
26 * 32 bit support. Whee!
28 * 8 4/09/99 2:21p Dave
29 * Multiplayer beta stuff. CD checking.
31 * 7 1/14/99 12:48a Dave
32 * Todo list bug fixes. Made a pass at putting briefing icons back into
33 * FRED. Sort of works :(
35 * 6 12/01/98 5:53p Dave
36 * Simplified the way pixel data is swizzled. Fixed tga bitmaps to work
37 * properly in D3D and Glide.
39 * 5 12/01/98 8:06a Dave
40 * Temporary checkin to fix some texture transparency problems in d3d.
42 * 4 11/30/98 1:07p Dave
43 * 16 bit conversion, first run.
45 * 3 10/22/98 6:14p Dave
46 * Optimized some #includes in Anim folder. Put in the beginnings of
47 * parse/localization support for externalized strings and tstrings.tbl
49 * 2 10/07/98 10:52a Dave
52 * 1 10/07/98 10:48a Dave
54 * 30 5/14/98 3:38p John
55 * Added in more non-darkening colors for Adam. Had to fix some bugs in
56 * BmpMan and Ani stuff to get this to work.
58 * 29 5/07/98 3:11a Lawrance
59 * Implement custom streaming code
61 * 28 11/19/97 8:28p Dave
62 * Hooked in Main Hall screen. Put in Anim support for ping ponging
63 * animations as well as general reversal of anim direction.
65 * 27 9/09/97 3:39p Sandeep
66 * warning level 4 bugs
68 * 26 8/22/97 8:21a Lawrance
69 * short circuit key frame check if keyframe matches frame we are
72 * 25 8/21/97 5:11p Lawrance
73 * frame numbering for ANI's now is from 0 -> total_frames-1.
75 * 24 8/19/97 10:59a Lawrance
76 * fix problem with accessing key frames
78 * 23 7/28/97 10:42p Lawrance
79 * re-did interface to unpack_frame() to make more general
81 * 22 7/28/97 10:52a Lawrance
82 * correctly set bitmap flags in anim_get_frame()
84 * 21 7/21/97 5:10p Lawrance
85 * fix problem that was causing infinite recursion
87 * 20 7/20/97 6:57p Lawrance
88 * supporting new RLE format
90 * 19 6/27/97 4:36p Lawrance
91 * update pal translation table when gr_screen.signature changes
93 * 18 6/26/97 12:12a Lawrance
94 * supporting anti-aliased bitmap animations
96 * 17 6/25/97 3:03p Lawrance
97 * fix palette translation problem with anti-alised bitmaps
99 * 16 5/19/97 2:28p Lawrance
100 * changes some variables to flags
102 * 15 5/15/97 4:42p Lawrance
103 * supporting animations in-game
105 * 14 2/25/97 11:06a Lawrance
106 * moved some higher level functions to from PackUnpack to AnimPlay
108 * 13 2/19/97 9:51p Lawrance
109 * made keyframe decompression more effecient, moved
110 * default anim FPS to header file
112 * 12 2/19/97 4:00p Lawrance
113 * don't assert when cannot find anim filename, return a NULL instead
115 * 11 2/17/97 4:17p Hoffoss
116 * modified packing internal format and added random access function to an
119 * 10 2/17/97 2:59p Lawrance
120 * integrating into game
122 * 9 2/14/97 11:27p Lawrance
123 * optimized unpacking some more (Jason)
125 * 8 2/14/97 11:09p Hoffoss
126 * Made optimizations.
128 * 7 2/14/97 10:48p Hoffoss
131 * 6 2/14/97 10:38p Lawrance
134 * 5 2/14/97 5:38p Hoffoss
135 * Changes to get AnimCoverter project to compile and link.
137 * 4 2/14/97 3:29p Hoffoss
138 * Added header for MSDEV to fill in.
143 #include "grinternal.h"
147 #include "animplay.h"
148 #include "packunpack.h"
150 int packer_code = PACKER_CODE;
151 int transparent_code = 254;
153 void anim_check_for_palette_change(anim_instance *instance) {
154 if ( instance->parent->screen_sig != gr_screen.signature ) {
155 instance->parent->screen_sig = gr_screen.signature;
156 anim_set_palette(instance->parent);
160 anim_instance *init_anim_instance(anim *ptr, int bpp)
169 if ( ptr->flags & ANF_STREAMED ) {
170 if ( ptr->file_offset < 0 ) {
181 ptr->instance_count++;
182 inst = (anim_instance *) malloc(sizeof(anim_instance));
184 inst->frame_num = -1;
185 inst->last_frame_num = -1;
187 inst->data = ptr->data;
188 inst->file_offset = ptr->file_offset;
189 inst->stop_now = FALSE;
190 inst->aa_color = NULL;
193 inst->frame = (ubyte *) malloc(inst->parent->width * inst->parent->height * 2);
195 inst->frame = (ubyte *) malloc(inst->parent->width * inst->parent->height);
200 void free_anim_instance(anim_instance *inst)
205 inst->parent->instance_count--;
208 inst->file_offset = -1;
213 int anim_get_next_frame(anim_instance *inst)
215 int bm, bitmap_flags;
219 if ( anim_instance_is_streamed(inst) ) {
220 if ( inst->file_offset <= 0 ) {
229 if (inst->frame_num >= inst->parent->total_frames) {
231 inst->file_offset = inst->parent->file_offset;
235 if (inst->parent->flags & ANF_XPARENT) {
236 // bitmap_flags = BMP_XPARENT;
243 if(inst->aa_color != NULL){
244 bitmap_flags |= BMP_AABITMAP;
249 anim_check_for_palette_change(inst);
251 // if we're using bitmap polys
253 BM_SELECT_TEX_FORMAT();
256 if ( anim_instance_is_streamed(inst) ) {
257 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
259 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
262 bm = bm_create(bpp, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
267 ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp)
269 if ( anim_instance_is_streamed(inst) ) {
270 if ( inst->file_offset < 0 ) {
280 if (inst->frame_num >= inst->parent->total_frames) {
282 inst->file_offset = inst->parent->file_offset;
286 anim_check_for_palette_change(inst);
288 if ( anim_instance_is_streamed(inst) ) {
290 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
292 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
296 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
298 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
305 // --------------------------------------------------------------------
308 // Get a bitmap id from the anim_instance for the specified frame_num
310 // input: *inst => pointer to anim instance
311 // frame_num => frame number to get (first frame is 0)
312 // xlate_pal => DEFAULT PARM (value 1): whether to translate the palette
313 // to the current game palette
315 int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal)
318 int bm, bitmap_flags, key = 0, offset = 0;
321 if ((frame_num < 0) || (frame_num >= inst->parent->total_frames)) // illegal frame number
325 if ( anim_instance_is_streamed(inst) ) {
326 if ( inst->file_offset < 0 ) {
335 if (need_reset || (inst->frame_num >= inst->parent->total_frames)) { // reset to valid info
336 inst->data = inst->parent->data;
337 inst->file_offset = inst->parent->file_offset;
342 if (inst->parent->flags & ANF_XPARENT) {
343 // bitmap_flags = BMP_XPARENT;
347 if ( inst->frame_num == frame_num ) {
348 bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
353 if (inst->parent->flags & ANF_XPARENT){
354 // bitmap_flags = BMP_XPARENT;
362 while(idx < inst->parent->num_keys){
363 if (( (inst->parent->keys[idx].frame_num-1) <= frame_num) && ( (inst->parent->keys[idx].frame_num-1) > key)) { // find closest key
364 key = inst->parent->keys[idx].frame_num - 1;
365 offset = inst->parent->keys[idx].offset;
367 if ( key == frame_num )
373 if ( key == frame_num ) {
374 inst->frame_num = key;
376 if ( anim_instance_is_streamed(inst) ) {
377 inst->file_offset = inst->parent->file_offset + offset;
379 inst->data = inst->parent->data + offset;
382 anim_check_for_palette_change(inst);
384 if ( anim_instance_is_streamed(inst) ) {
386 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
388 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
392 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
394 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
401 if (key > inst->frame_num) // best key is closer than current position
403 inst->frame_num = key;
405 if ( anim_instance_is_streamed(inst) ) {
406 inst->file_offset = inst->parent->file_offset + offset;
408 inst->data = inst->parent->data + offset;
411 anim_check_for_palette_change(inst);
413 if ( anim_instance_is_streamed(inst) ) {
415 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
417 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
420 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
422 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
426 while (inst->frame_num != frame_num) {
427 anim_check_for_palette_change(inst);
429 if ( anim_instance_is_streamed(inst) ) {
431 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
433 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
436 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
438 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
445 bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
453 // frame = frame pixel data to pack
454 // save = memory to store packed data to
455 // size = number of bytes to pack
456 // max = maximum number of packed bytes (size of buffer)
457 // returns: actual number of bytes data packed to or -1 if error
458 int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
460 int last = -32768, count = 0;
461 long packed_size = 1;
463 switch ( compress_type ) {
464 case PACKING_METHOD_RLE_KEY:
465 *save++ = PACKING_METHOD_RLE_KEY;
467 if (*frame != last || count > 255) {
468 if (packed_size + 3 >= max)
472 if (last == packer_code) {
473 *save++ = (ubyte)packer_code;
474 *save++ = (ubyte)(count - 1);
479 *save++ = (ubyte)last;
484 *save++ = (ubyte)packer_code;
485 *save++ = (ubyte)(count - 1);
486 *save++ = (ubyte)last;
498 if (packed_size + 3 >= max)
502 if (last == packer_code) {
503 *save++ = (ubyte)packer_code;
504 *save++ = (ubyte)(count - 1);
509 *save++ = (ubyte)last;
514 *save++ = (ubyte)packer_code;
515 *save++ = (ubyte)(count - 1);
516 *save++ = (ubyte)last;
521 case PACKING_METHOD_STD_RLE_KEY: {
529 *save++ = PACKING_METHOD_STD_RLE_KEY;
530 for (i=1; i < size; i++ ) {
532 if ( *frame != last ) {
535 if (packed_size + 2 >= max)
538 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
539 *save++ = (ubyte)last;
541 Assert( last != STD_RLE_CODE );
542 // printf("Just packed %d 1 times, since pixel change, no count included\n",last);
545 count |= STD_RLE_CODE;
546 *save++ = (ubyte)count;
547 *save++ = (ubyte)last;
549 // printf("Just packed %d %d times, since pixel change\n",last,count);
560 if ( count == 127 ) {
561 count |= STD_RLE_CODE;
562 *save++ = (ubyte)count;
563 *save++ = (ubyte)last;
566 // printf("Just packed %d %d times, since count overflow\n",last,count);
573 if (packed_size + 2 >= max)
576 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
577 *save++ = (ubyte)last;
579 // printf("Just packed %d 1 times, at end since single pixel, no count\n",last);
580 Assert( last != STD_RLE_CODE );
583 count |= STD_RLE_CODE;
584 *save++ = (ubyte)count;
585 *save++ = (ubyte)last;
587 // printf("Just packed %d %d times, at end since pixel change\n",last,count);
591 Assert(packed_size == (save-dest_start) );
605 // frame = frame pixel data to pack
606 // frame2 = previous frame's pixel data
607 // save = memory to store packed data to
608 // size = number of bytes to pack
609 // max = maximum number of packed bytes (size of buffer)
610 // returns: actual number of bytes data packed to or -1 if error
611 int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
613 int pixel, last = -32768, count = 0, i;
614 long packed_size = 1;
616 switch ( compress_type ) {
617 case PACKING_METHOD_RLE: // Hoffoss RLE regular frame
618 *save++ = PACKING_METHOD_RLE;
620 if (*frame != *frame2++)
623 pixel = transparent_code;
625 if (pixel != last || count > 255) {
626 if (packed_size + 3 >= max)
630 if (last == packer_code) {
631 *save++ = (ubyte)packer_code;
632 *save++ = (ubyte)(count - 1);
637 *save++ = (ubyte)last;
642 *save++ = (ubyte)packer_code;
643 *save++ = (ubyte)(count - 1);
644 *save++ = (ubyte)last;
656 if (packed_size + 3 >= max)
660 if (last == packer_code) {
661 *save++ = (ubyte)packer_code;
662 *save++ = (ubyte)(count - 1);
667 *save++ = (ubyte)last;
672 *save++ = (ubyte)(packer_code);
673 *save++ = (ubyte)(count - 1);
674 *save++ = (ubyte)(last);
679 case PACKING_METHOD_STD_RLE: { // high bit count regular RLE frame
686 if (*frame++ != *frame2++)
689 last = transparent_code;
691 *save++ = PACKING_METHOD_STD_RLE;
692 for (i=1; i < size; i++ ) {
694 if (*frame != *frame2++)
697 pixel = transparent_code;
699 if ( pixel != last ) {
702 if (packed_size + 2 >= max)
705 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
706 *save++ = (ubyte)last;
708 Assert( last != STD_RLE_CODE );
711 count |= STD_RLE_CODE;
712 *save++ = (ubyte)count;
713 *save++ = (ubyte)last;
725 if ( count == 127 ) {
726 count |= STD_RLE_CODE;
727 *save++ = (ubyte)count;
728 *save++ = (ubyte)last;
736 if (packed_size + 2 >= max)
739 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
740 *save++ = (ubyte)last;
742 Assert( last != STD_RLE_CODE );
745 count |= STD_RLE_CODE;
746 *save++ = (ubyte)count;
747 *save++ = (ubyte)last;
752 Assert(packed_size == (save-dest_start) );
766 // unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
767 int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
774 anim *a = ai->parent;
777 // if this is an aabitmap, don't run through the palette
781 bit_16 = (ushort)pix;
790 // if the pixel value is 255, or is the xparent color, make it so
791 if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
794 bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
796 // stuff the 24 bit value
797 memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
800 bm_24_to_16(bit_24, &bit_16);
807 memcpy(data, &bit_16, sizeof(ushort));
808 return sizeof(ushort);
812 return sizeof(ubyte);
819 // unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
820 int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count, int aabitmap, int bpp)
827 anim *a = ai->parent;
831 // if this is an aabitmap, don't run through the palette
835 bit_16 = (ushort)pix;
844 // if the pixel value is 255, or is the xparent color, make it so
845 if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
848 bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
850 // stuff the 24 bit value
851 memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
854 bm_24_to_16(bit_24, &bit_16);
859 for(idx=0; idx<count; idx++){
862 memcpy(data + (idx*2), &bit_16, sizeof(ushort));
865 *(data + idx) = bit_8;
871 return sizeof(ushort) * count;
873 return sizeof(ubyte) * count;
876 // ptr = packed data to unpack
877 // frame = where to store unpacked data to
878 // size = total number of unpacked pixels requested
879 // pal_translate = color translation lookup table (NULL if no palette translation desired)
880 ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
882 int xlate_pal, value, count = 0;
884 int pixel_size = (bpp == 16) ? 2 : 1;
886 if ( pal_translate == NULL ) {
893 if (*ptr == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
897 if (value != packer_code) {
899 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
901 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
918 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
920 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
928 else if ( *ptr == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
932 if ( !(value & STD_RLE_CODE) ) {
934 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
936 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
942 count = value & (~STD_RLE_CODE);
949 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
951 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
958 else if (*ptr == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
960 // test code, to show unused pixels
961 // memset(frame, 255, size);
966 if (value != packer_code) {
967 if (value != transparent_code) {
969 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
971 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
975 stuffed = pixel_size;
995 if (value != transparent_code ) {
997 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
999 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1002 stuffed = count * pixel_size;
1010 else if ( *ptr == PACKING_METHOD_STD_RLE) { // normal frame, with high bit as count
1014 if ( !(value & STD_RLE_CODE) ) {
1015 if (value != transparent_code) {
1017 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1019 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1022 stuffed = pixel_size;
1028 count = value & (~STD_RLE_CODE);
1034 if (value != transparent_code) {
1036 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1038 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1041 stuffed = pixel_size * count;
1049 Assert(0); // unknown packing method
1055 // ptr = packed data to unpack
1056 // frame = where to store unpacked data to
1057 // size = total number of unpacked pixels requested
1058 // pal_translate = color translation lookup table (NULL if no palette translation desired)
1059 int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
1061 int xlate_pal, value, count = 0;
1064 int pixel_size = (bpp == 16) ? 2 : 1;
1066 if ( pal_translate == NULL ) {
1073 if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
1076 value = anim_instance_get_byte(ai,offset);
1078 if (value != packer_code) {
1080 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1082 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1088 count = anim_instance_get_byte(ai,offset);
1091 value = packer_code;
1093 value = anim_instance_get_byte(ai,offset);
1097 if (++count > size){
1102 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1104 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1112 else if ( anim_instance_get_byte(ai,offset) == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
1115 value = anim_instance_get_byte(ai,offset);
1117 if ( !(value & STD_RLE_CODE) ) {
1119 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1121 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1127 count = value & (~STD_RLE_CODE);
1128 value = anim_instance_get_byte(ai,offset);
1135 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1137 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1144 else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
1146 // test code, to show unused pixels
1147 // memset(frame, 255, size);
1151 value = anim_instance_get_byte(ai,offset);
1153 if (value != packer_code) {
1154 if (value != transparent_code) {
1156 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1158 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1161 stuffed = pixel_size;
1167 count = anim_instance_get_byte(ai,offset);
1171 value = packer_code;
1173 value = anim_instance_get_byte(ai,offset);
1176 if (++count > size){
1183 if (value != transparent_code ) {
1185 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1187 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1190 stuffed = pixel_size * count;
1198 else if ( anim_instance_get_byte(ai,offset) ) { // normal frame, with high bit as count
1201 value = anim_instance_get_byte(ai,offset);
1203 if ( !(value & STD_RLE_CODE) ) {
1204 if (value != transparent_code) {
1206 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1208 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1211 stuffed = pixel_size;
1217 count = value & (~STD_RLE_CODE);
1218 value = anim_instance_get_byte(ai,offset);
1224 if (value != transparent_code) {
1226 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1228 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1231 stuffed = pixel_size * count;
1239 Int3(); // unknown packing method
1242 return ai->file_offset + offset;
1246 // TODO: actually convert the frame data to correct palette at this point
1247 void anim_set_palette(anim *ptr)
1249 int i, xparent_found = 0;
1251 // create the palette translation look-up table
1252 for ( i = 0; i < 256; i++ ) {
1254 //if ( (ptr->palette[i*3] == ptr->xparent_r) && (ptr->palette[i*3+1] == ptr->xparent_g) && (ptr->palette[i*3+2] == ptr->xparent_b) ) {
1255 // ptr->palette_translation[i] = 255;
1256 // xparent_found = 1;
1258 // ptr->palette_translation[i] = (ubyte)palette_find( ptr->palette[i*3], ptr->palette[i*3+1], ptr->palette[i*3+2] );
1259 ptr->palette_translation[i] = (ubyte)i;
1263 if ( xparent_found ) {
1264 ptr->flags |= ANF_XPARENT;
1267 ptr->flags &= ~ANF_XPARENT;