2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Anim/PackUnpack.cpp $
15 * Code for handling packing and unpacking in Hoffoss's RLE format, used for
16 * Anim files. Also handles Anim loading, creating Anim instances (for
17 * utilizing an Anim), and getting getting frames of the Anim.
20 * Revision 1.2 2002/06/09 04:41:15 relnev
21 * added copyright header
23 * Revision 1.1.1.1 2002/05/03 03:28:08 root
27 * 12 7/30/99 10:10p Dave
28 * Fixed loading bar in 32 bit mode.
30 * 11 7/18/99 1:59p Johnson
31 * Fixed potential anim locking problem.
33 * 10 7/16/99 1:49p Dave
34 * 8 bit aabitmaps. yay.
36 * 9 7/13/99 1:15p Dave
37 * 32 bit support. Whee!
39 * 8 4/09/99 2:21p Dave
40 * Multiplayer beta stuff. CD checking.
42 * 7 1/14/99 12:48a Dave
43 * Todo list bug fixes. Made a pass at putting briefing icons back into
44 * FRED. Sort of works :(
46 * 6 12/01/98 5:53p Dave
47 * Simplified the way pixel data is swizzled. Fixed tga bitmaps to work
48 * properly in D3D and Glide.
50 * 5 12/01/98 8:06a Dave
51 * Temporary checkin to fix some texture transparency problems in d3d.
53 * 4 11/30/98 1:07p Dave
54 * 16 bit conversion, first run.
56 * 3 10/22/98 6:14p Dave
57 * Optimized some #includes in Anim folder. Put in the beginnings of
58 * parse/localization support for externalized strings and tstrings.tbl
60 * 2 10/07/98 10:52a Dave
63 * 1 10/07/98 10:48a Dave
65 * 30 5/14/98 3:38p John
66 * Added in more non-darkening colors for Adam. Had to fix some bugs in
67 * BmpMan and Ani stuff to get this to work.
69 * 29 5/07/98 3:11a Lawrance
70 * Implement custom streaming code
72 * 28 11/19/97 8:28p Dave
73 * Hooked in Main Hall screen. Put in Anim support for ping ponging
74 * animations as well as general reversal of anim direction.
76 * 27 9/09/97 3:39p Sandeep
77 * warning level 4 bugs
79 * 26 8/22/97 8:21a Lawrance
80 * short circuit key frame check if keyframe matches frame we are
83 * 25 8/21/97 5:11p Lawrance
84 * frame numbering for ANI's now is from 0 -> total_frames-1.
86 * 24 8/19/97 10:59a Lawrance
87 * fix problem with accessing key frames
89 * 23 7/28/97 10:42p Lawrance
90 * re-did interface to unpack_frame() to make more general
92 * 22 7/28/97 10:52a Lawrance
93 * correctly set bitmap flags in anim_get_frame()
95 * 21 7/21/97 5:10p Lawrance
96 * fix problem that was causing infinite recursion
98 * 20 7/20/97 6:57p Lawrance
99 * supporting new RLE format
101 * 19 6/27/97 4:36p Lawrance
102 * update pal translation table when gr_screen.signature changes
104 * 18 6/26/97 12:12a Lawrance
105 * supporting anti-aliased bitmap animations
107 * 17 6/25/97 3:03p Lawrance
108 * fix palette translation problem with anti-alised bitmaps
110 * 16 5/19/97 2:28p Lawrance
111 * changes some variables to flags
113 * 15 5/15/97 4:42p Lawrance
114 * supporting animations in-game
116 * 14 2/25/97 11:06a Lawrance
117 * moved some higher level functions to from PackUnpack to AnimPlay
119 * 13 2/19/97 9:51p Lawrance
120 * made keyframe decompression more effecient, moved
121 * default anim FPS to header file
123 * 12 2/19/97 4:00p Lawrance
124 * don't assert when cannot find anim filename, return a NULL instead
126 * 11 2/17/97 4:17p Hoffoss
127 * modified packing internal format and added random access function to an
130 * 10 2/17/97 2:59p Lawrance
131 * integrating into game
133 * 9 2/14/97 11:27p Lawrance
134 * optimized unpacking some more (Jason)
136 * 8 2/14/97 11:09p Hoffoss
137 * Made optimizations.
139 * 7 2/14/97 10:48p Hoffoss
142 * 6 2/14/97 10:38p Lawrance
145 * 5 2/14/97 5:38p Hoffoss
146 * Changes to get AnimCoverter project to compile and link.
148 * 4 2/14/97 3:29p Hoffoss
149 * Added header for MSDEV to fill in.
154 #include "grinternal.h"
158 #include "animplay.h"
159 #include "packunpack.h"
161 int packer_code = PACKER_CODE;
162 int transparent_code = 254;
164 void anim_check_for_palette_change(anim_instance *instance) {
165 if ( instance->parent->screen_sig != gr_screen.signature ) {
166 instance->parent->screen_sig = gr_screen.signature;
167 anim_set_palette(instance->parent);
171 anim_instance *init_anim_instance(anim *ptr, int bpp)
180 if ( ptr->flags & ANF_STREAMED ) {
181 if ( ptr->file_offset < 0 ) {
192 ptr->instance_count++;
193 inst = (anim_instance *) malloc(sizeof(anim_instance));
195 inst->frame_num = -1;
196 inst->last_frame_num = -1;
198 inst->data = ptr->data;
199 inst->file_offset = ptr->file_offset;
200 inst->stop_now = FALSE;
201 inst->aa_color = NULL;
204 inst->frame = (ubyte *) malloc(inst->parent->width * inst->parent->height * 2);
206 inst->frame = (ubyte *) malloc(inst->parent->width * inst->parent->height);
211 void free_anim_instance(anim_instance *inst)
213 SDL_assert(inst->frame);
216 inst->parent->instance_count--;
219 inst->file_offset = -1;
224 int anim_get_next_frame(anim_instance *inst)
226 int bm, bitmap_flags;
230 if ( anim_instance_is_streamed(inst) ) {
231 if ( inst->file_offset <= 0 ) {
240 if (inst->frame_num >= inst->parent->total_frames) {
242 inst->file_offset = inst->parent->file_offset;
246 if (inst->parent->flags & ANF_XPARENT) {
247 // bitmap_flags = BMP_XPARENT;
254 if(inst->aa_color != NULL){
255 bitmap_flags |= BMP_AABITMAP;
260 anim_check_for_palette_change(inst);
262 // if we're using bitmap polys
263 BM_SELECT_TEX_FORMAT();
265 if ( anim_instance_is_streamed(inst) ) {
266 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
268 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
271 bm = bm_create(bpp, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
276 ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp)
278 if ( anim_instance_is_streamed(inst) ) {
279 if ( inst->file_offset < 0 ) {
289 if (inst->frame_num >= inst->parent->total_frames) {
291 inst->file_offset = inst->parent->file_offset;
295 anim_check_for_palette_change(inst);
297 if ( anim_instance_is_streamed(inst) ) {
299 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
301 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
305 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
307 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
314 // --------------------------------------------------------------------
317 // Get a bitmap id from the anim_instance for the specified frame_num
319 // input: *inst => pointer to anim instance
320 // frame_num => frame number to get (first frame is 0)
321 // xlate_pal => DEFAULT PARM (value 1): whether to translate the palette
322 // to the current game palette
324 int anim_get_frame(anim_instance *inst, int frame_num, int xlate_pal)
327 int bm, bitmap_flags, key = 0, offset = 0;
330 if ((frame_num < 0) || (frame_num >= inst->parent->total_frames)) // illegal frame number
334 if ( anim_instance_is_streamed(inst) ) {
335 if ( inst->file_offset < 0 ) {
344 if (need_reset || (inst->frame_num >= inst->parent->total_frames)) { // reset to valid info
345 inst->data = inst->parent->data;
346 inst->file_offset = inst->parent->file_offset;
351 if (inst->parent->flags & ANF_XPARENT) {
352 // bitmap_flags = BMP_XPARENT;
356 if ( inst->frame_num == frame_num ) {
357 bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
362 if (inst->parent->flags & ANF_XPARENT){
363 // bitmap_flags = BMP_XPARENT;
371 while(idx < inst->parent->num_keys){
372 if (( (inst->parent->keys[idx].frame_num-1) <= frame_num) && ( (inst->parent->keys[idx].frame_num-1) > key)) { // find closest key
373 key = inst->parent->keys[idx].frame_num - 1;
374 offset = inst->parent->keys[idx].offset;
376 if ( key == frame_num )
382 if ( key == frame_num ) {
383 inst->frame_num = key;
385 if ( anim_instance_is_streamed(inst) ) {
386 inst->file_offset = inst->parent->file_offset + offset;
388 inst->data = inst->parent->data + offset;
391 anim_check_for_palette_change(inst);
393 if ( anim_instance_is_streamed(inst) ) {
395 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
397 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
401 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
403 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
410 if (key > inst->frame_num) // best key is closer than current position
412 inst->frame_num = key;
414 if ( anim_instance_is_streamed(inst) ) {
415 inst->file_offset = inst->parent->file_offset + offset;
417 inst->data = inst->parent->data + offset;
420 anim_check_for_palette_change(inst);
422 if ( anim_instance_is_streamed(inst) ) {
424 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
426 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
429 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
431 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
435 while (inst->frame_num != frame_num) {
436 anim_check_for_palette_change(inst);
438 if ( anim_instance_is_streamed(inst) ) {
440 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
442 inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL);
445 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation);
447 inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL);
454 bm = bm_create(16, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
462 // frame = frame pixel data to pack
463 // save = memory to store packed data to
464 // size = number of bytes to pack
465 // max = maximum number of packed bytes (size of buffer)
466 // returns: actual number of bytes data packed to or -1 if error
467 int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
469 int last = -32768, count = 0;
470 long packed_size = 1;
472 switch ( compress_type ) {
473 case PACKING_METHOD_RLE_KEY:
474 *save++ = PACKING_METHOD_RLE_KEY;
476 if (*frame != last || count > 255) {
477 if (packed_size + 3 >= max)
481 if (last == packer_code) {
482 *save++ = (ubyte)packer_code;
483 *save++ = (ubyte)(count - 1);
488 *save++ = (ubyte)last;
493 *save++ = (ubyte)packer_code;
494 *save++ = (ubyte)(count - 1);
495 *save++ = (ubyte)last;
507 if (packed_size + 3 >= max)
511 if (last == packer_code) {
512 *save++ = (ubyte)packer_code;
513 *save++ = (ubyte)(count - 1);
518 *save++ = (ubyte)last;
523 *save++ = (ubyte)packer_code;
524 *save++ = (ubyte)(count - 1);
525 *save++ = (ubyte)last;
530 case PACKING_METHOD_STD_RLE_KEY: {
531 ubyte *dest_start = save;
537 *save++ = PACKING_METHOD_STD_RLE_KEY;
538 for (i=1; i < size; i++ ) {
540 if ( *frame != last ) {
543 if (packed_size + 2 >= max)
546 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
547 *save++ = (ubyte)last;
549 SDL_assert( last != STD_RLE_CODE );
550 // printf("Just packed %d 1 times, since pixel change, no count included\n",last);
553 count |= STD_RLE_CODE;
554 *save++ = (ubyte)count;
555 *save++ = (ubyte)last;
557 // printf("Just packed %d %d times, since pixel change\n",last,count);
568 if ( count == 127 ) {
569 count |= STD_RLE_CODE;
570 *save++ = (ubyte)count;
571 *save++ = (ubyte)last;
574 // printf("Just packed %d %d times, since count overflow\n",last,count);
581 if (packed_size + 2 >= max)
584 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
585 *save++ = (ubyte)last;
587 // printf("Just packed %d 1 times, at end since single pixel, no count\n",last);
588 SDL_assert( last != STD_RLE_CODE );
591 count |= STD_RLE_CODE;
592 *save++ = (ubyte)count;
593 *save++ = (ubyte)last;
595 // printf("Just packed %d %d times, at end since pixel change\n",last,count);
599 SDL_assert(packed_size == (save-dest_start) );
613 // frame = frame pixel data to pack
614 // frame2 = previous frame's pixel data
615 // save = memory to store packed data to
616 // size = number of bytes to pack
617 // max = maximum number of packed bytes (size of buffer)
618 // returns: actual number of bytes data packed to or -1 if error
619 int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
621 int pixel, last = -32768, count = 0, i;
622 long packed_size = 1;
624 switch ( compress_type ) {
625 case PACKING_METHOD_RLE: // Hoffoss RLE regular frame
626 *save++ = PACKING_METHOD_RLE;
628 if (*frame != *frame2++)
631 pixel = transparent_code;
633 if (pixel != last || count > 255) {
634 if (packed_size + 3 >= max)
638 if (last == packer_code) {
639 *save++ = (ubyte)packer_code;
640 *save++ = (ubyte)(count - 1);
645 *save++ = (ubyte)last;
650 *save++ = (ubyte)packer_code;
651 *save++ = (ubyte)(count - 1);
652 *save++ = (ubyte)last;
664 if (packed_size + 3 >= max)
668 if (last == packer_code) {
669 *save++ = (ubyte)packer_code;
670 *save++ = (ubyte)(count - 1);
675 *save++ = (ubyte)last;
680 *save++ = (ubyte)(packer_code);
681 *save++ = (ubyte)(count - 1);
682 *save++ = (ubyte)(last);
687 case PACKING_METHOD_STD_RLE: { // high bit count regular RLE frame
689 ubyte *dest_start = save;
693 if (*frame++ != *frame2++)
696 last = transparent_code;
698 *save++ = PACKING_METHOD_STD_RLE;
699 for (i=1; i < size; i++ ) {
701 if (*frame != *frame2++)
704 pixel = transparent_code;
706 if ( pixel != last ) {
709 if (packed_size + 2 >= max)
712 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
713 *save++ = (ubyte)last;
715 SDL_assert( last != STD_RLE_CODE );
718 count |= STD_RLE_CODE;
719 *save++ = (ubyte)count;
720 *save++ = (ubyte)last;
732 if ( count == 127 ) {
733 count |= STD_RLE_CODE;
734 *save++ = (ubyte)count;
735 *save++ = (ubyte)last;
743 if (packed_size + 2 >= max)
746 if ( (count == 1) && !(last & STD_RLE_CODE) ) {
747 *save++ = (ubyte)last;
749 SDL_assert( last != STD_RLE_CODE );
752 count |= STD_RLE_CODE;
753 *save++ = (ubyte)count;
754 *save++ = (ubyte)last;
759 SDL_assert(packed_size == (save-dest_start) );
773 // unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
774 int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
781 anim *a = ai->parent;
784 // if this is an aabitmap, don't run through the palette
788 bit_16 = (ushort)pix;
797 // if the pixel value is 255, or is the xparent color, make it so
798 if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
801 bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
803 // stuff the 24 bit value
804 memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
807 bm_24_to_16(bit_24, &bit_16);
814 memcpy(data, &bit_16, sizeof(ushort));
815 return sizeof(ushort);
819 return sizeof(ubyte);
826 // unpack a pixel given the passed index and the anim_instance's palette, return bytes stuffed
827 int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count, int aabitmap, int bpp)
834 anim *a = ai->parent;
838 // if this is an aabitmap, don't run through the palette
842 bit_16 = (ushort)pix;
851 // if the pixel value is 255, or is the xparent color, make it so
852 if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
855 bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
857 // stuff the 24 bit value
858 memcpy(&bit_24, &ai->parent->palette[pix * 3], 3);
861 bm_24_to_16(bit_24, &bit_16);
866 for(idx=0; idx<count; idx++){
869 memcpy(data + (idx*2), &bit_16, sizeof(ushort));
872 *(data + idx) = bit_8;
878 return sizeof(ushort) * count;
880 return sizeof(ubyte) * count;
883 // ptr = packed data to unpack
884 // frame = where to store unpacked data to
885 // size = total number of unpacked pixels requested
886 // pal_translate = color translation lookup table (NULL if no palette translation desired)
887 ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
889 int xlate_pal, value, count = 0;
891 int pixel_size = (bpp == 16) ? 2 : 1;
893 if ( pal_translate == NULL ) {
900 if (*ptr == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
904 if (value != packer_code) {
906 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
908 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
925 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
927 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
935 else if ( *ptr == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
939 if ( !(value & STD_RLE_CODE) ) {
941 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
943 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
949 count = value & (~STD_RLE_CODE);
953 SDL_assert(size >= 0);
956 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
958 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
965 else if (*ptr == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
967 // test code, to show unused pixels
968 // memset(frame, 255, size);
973 if (value != packer_code) {
974 if (value != transparent_code) {
976 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
978 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
982 stuffed = pixel_size;
1000 SDL_assert(size >= 0);
1002 if (value != transparent_code ) {
1004 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1006 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1009 stuffed = count * pixel_size;
1017 else if ( *ptr == PACKING_METHOD_STD_RLE) { // normal frame, with high bit as count
1021 if ( !(value & STD_RLE_CODE) ) {
1022 if (value != transparent_code) {
1024 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1026 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1029 stuffed = pixel_size;
1035 count = value & (~STD_RLE_CODE);
1039 SDL_assert(size >= 0);
1041 if (value != transparent_code) {
1043 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1045 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1048 stuffed = pixel_size * count;
1056 SDL_assert(0); // unknown packing method
1062 // ptr = packed data to unpack
1063 // frame = where to store unpacked data to
1064 // size = total number of unpacked pixels requested
1065 // pal_translate = color translation lookup table (NULL if no palette translation desired)
1066 int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
1068 int xlate_pal, value, count = 0;
1071 int pixel_size = (bpp == 16) ? 2 : 1;
1073 if ( pal_translate == NULL ) {
1080 if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
1083 value = anim_instance_get_byte(ai,offset);
1085 if (value != packer_code) {
1087 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1089 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1095 count = anim_instance_get_byte(ai,offset);
1098 value = packer_code;
1100 value = anim_instance_get_byte(ai,offset);
1104 if (++count > size){
1109 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1111 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1119 else if ( anim_instance_get_byte(ai,offset) == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
1122 value = anim_instance_get_byte(ai,offset);
1124 if ( !(value & STD_RLE_CODE) ) {
1126 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1128 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1134 count = value & (~STD_RLE_CODE);
1135 value = anim_instance_get_byte(ai,offset);
1139 SDL_assert(size >= 0);
1142 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1144 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1151 else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
1153 // test code, to show unused pixels
1154 // memset(frame, 255, size);
1158 value = anim_instance_get_byte(ai,offset);
1160 if (value != packer_code) {
1161 if (value != transparent_code) {
1163 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1165 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1168 stuffed = pixel_size;
1174 count = anim_instance_get_byte(ai,offset);
1178 value = packer_code;
1180 value = anim_instance_get_byte(ai,offset);
1183 if (++count > size){
1188 SDL_assert(size >= 0);
1190 if (value != transparent_code ) {
1192 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1194 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1197 stuffed = pixel_size * count;
1205 else if ( anim_instance_get_byte(ai,offset) ) { // normal frame, with high bit as count
1208 value = anim_instance_get_byte(ai,offset);
1210 if ( !(value & STD_RLE_CODE) ) {
1211 if (value != transparent_code) {
1213 stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1215 stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1218 stuffed = pixel_size;
1224 count = value & (~STD_RLE_CODE);
1225 value = anim_instance_get_byte(ai,offset);
1229 SDL_assert(size >= 0);
1231 if (value != transparent_code) {
1233 stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1235 stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1238 stuffed = pixel_size * count;
1246 Int3(); // unknown packing method
1249 return ai->file_offset + offset;
1253 // TODO: actually convert the frame data to correct palette at this point
1254 void anim_set_palette(anim *ptr)
1256 int i, xparent_found = 0;
1258 // create the palette translation look-up table
1259 for ( i = 0; i < 256; i++ ) {
1261 //if ( (ptr->palette[i*3] == ptr->xparent_r) && (ptr->palette[i*3+1] == ptr->xparent_g) && (ptr->palette[i*3+2] == ptr->xparent_b) ) {
1262 // ptr->palette_translation[i] = 255;
1263 // xparent_found = 1;
1265 // ptr->palette_translation[i] = (ubyte)palette_find( ptr->palette[i*3], ptr->palette[i*3+1], ptr->palette[i*3+2] );
1266 ptr->palette_translation[i] = (ubyte)i;
1270 if ( xparent_found ) {
1271 ptr->flags |= ANF_XPARENT;
1274 ptr->flags &= ~ANF_XPARENT;