This is xanim_pfx.c in view mode; [Download] [Up]
/* * xanim_pfx.c * * Copyright (C) 1992,1993,1994 by Mark Podlipec. * All rights reserved. * * This software may be freely copied, modified and redistributed without * fee for non-commerical purposes provided that this copyright notice is * preserved intact on all copies and modified copies. * * There is no warranty or other guarantee of fitness of this software. * It is provided solely "as is". The author(s) disclaim(s) all * responsibility and liability with respect to this software's usage * or its effect upon hardware or computer systems. * */ #include "xanim_pfx.h" #include "xanim_iff.h" LONG Is_PFX_File(); ULONG PFX_Read_File(); void PFX_Setup_CMAP(); void PFX_Extract_Images(); ULONG UTIL_Get_MSB_Long(); ULONG UTIL_Get_MSB_UShort(); XA_CHDR *ACT_Get_CMAP(); XA_ACTION *ACT_Get_Action(); void ACT_Setup_Mapped(); void ACT_Add_CHDR_To_Action(); static PFX_PLAY_HDR *pfx_play_stack,*pfx_play_start,*pfx_play_lcur; static XA_CHDR *pfx_chdr; static ColorReg pfx_cmap[256]; #define PFX_DEFAULT_TIME 17 static LONG pfx_time; static PFX_RCHG_HDR *pfx_images; static ULONG pfx_imagex,pfx_imagey,pfx_imagec,pfx_imaged; /* * */ LONG Is_PFX_File(filename) char *filename; { FILE *fin; ULONG data; if ( (fin=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE); data = UTIL_Get_MSB_Long(fin); /* read past size */ data = UTIL_Get_MSB_Long(fin); /* read magic */ fclose(fin); if (data == pfx_RCHG) return(TRUE); return(FALSE); } void PFX_PUSH_PLAY_HDR(p) PFX_PLAY_HDR *p; { PFX_PLAY_HDR *temp; temp = (PFX_PLAY_HDR *) malloc(sizeof(PFX_PLAY_HDR)); if (temp == 0) TheEnd1("PFX_PUSH_PLAY_HDR: malloc failed\n"); temp->type = p->type; temp->data = p->data; temp->count = 0; temp->next = 0; temp->loop = 0; if (pfx_play_start == 0) pfx_play_start = temp; else pfx_play_lcur->next = temp; pfx_play_lcur = temp; DEBUG_LEVEL2 fprintf(stderr,"PUSHING %c%c%c%c", ((p->type >> 24) & 0xff), ((p->type >> 16) & 0xff), ((p->type >> 8) & 0xff), ((p->type) & 0xff) ); DEBUG_LEVEL2 fprintf(stderr," data=%lx ptr=%lx\n", p->data,(ULONG)pfx_play_lcur); /* stack knows where it's duplicate is on play list */ p->loop = pfx_play_lcur; p->next = pfx_play_stack; pfx_play_stack = p; } PFX_PLAY_HDR *PFX_POP_PLAY_HDR() { PFX_PLAY_HDR *p; p = pfx_play_stack; if (p != 0) pfx_play_stack = pfx_play_stack->next; return(p); } PFX_RCHG_HDR *PFX_Alloc_RCHG() { PFX_RCHG_HDR *temp; temp = (PFX_RCHG_HDR *)malloc(sizeof(PFX_RCHG_HDR)); if (temp == 0) TheEnd1("PFX_Alloc_RCHG malloc error\n"); temp->orig = 0; temp->dest = 0; temp->len = 0; temp->data = 0; temp->next = 0; return(temp); } PFX_FRAM_HDR *PFX_Alloc_FRAM() { PFX_FRAM_HDR *temp; temp = (PFX_FRAM_HDR *)malloc(sizeof(PFX_FRAM_HDR)); if (temp == 0) TheEnd1("PFX_Alloc_FRAM malloc error\n"); temp->frame = 0; temp->time = 0; temp->next = 0; return(temp); } ULONG PFX_Read_File(fname,anim_hdr) char *fname; XA_ANIM_HDR *anim_hdr; { FILE *fin; PFX_RCHG_HDR *first_rchg,*cur_rchg; PFX_RCHG_HDR *first_parm,*cur_parm; PFX_FRAM_HDR *first_fram,*cur_fram; ULONG pfx_max_rchg; ULONG pfx_xflag,pfx_yflag,pfx_cflag,pfx_rchg_flag; ULONG d,chid,chlen; ULONG frame_count; PFX_PLAY_HDR *pfx_play_temp; pfx_play_stack = 0; pfx_play_start = 0; pfx_play_lcur = 0; pfx_chdr = 0; pfx_time = PFX_DEFAULT_TIME; pfx_images = 0; pfx_imagex = 0; pfx_imagey = 0; pfx_imagec = 0; pfx_imaged = 0; first_rchg = cur_rchg = 0; first_parm = cur_parm = 0; pfx_max_rchg = 0; pfx_xflag = FALSE; pfx_yflag = FALSE; pfx_cflag = FALSE; if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0) { fprintf(stderr,"Can't open PFX File %s for reading\n",fname); return(FALSE); } d = UTIL_Get_MSB_Long(fin); /* probably version number */ chid = UTIL_Get_MSB_Long(fin); /* get chunk id */ chlen = UTIL_Get_MSB_Long(fin); /* get chunk length */ while(chid == pfx_RCHG) { LONG ret; ULONG orig,dest,garb; PFX_RCHG_HDR *tmp_rchg; UBYTE *data; orig = UTIL_Get_MSB_UShort(fin); dest = UTIL_Get_MSB_UShort(fin); garb = UTIL_Get_MSB_Long(fin); /* orig ptr or id or ?? */ garb = UTIL_Get_MSB_Long(fin); /* dest ptr or id or ?? */ garb = UTIL_Get_MSB_UShort(fin); /* always 0xffff */ DEBUG_LEVEL1 fprintf(stderr,"RCHG %lx <%ld %ld>\n",chlen,orig,dest); chlen -= 14; data = (UBYTE *)malloc(chlen); if (data == 0) TheEnd1("PFX: rchg data malloc failed\n"); ret = fread((char *)(data),1,chlen,fin); if (ret != chlen) TheEnd1("PFX: rchg data read failed\n"); tmp_rchg = PFX_Alloc_RCHG(); tmp_rchg->orig = orig; tmp_rchg->dest = dest; tmp_rchg->len = chlen; tmp_rchg->data = data; if (first_rchg == 0) first_rchg = cur_rchg = tmp_rchg; else { cur_rchg->next = tmp_rchg; cur_rchg = tmp_rchg; } if (orig > pfx_max_rchg) pfx_max_rchg = orig; if (dest > pfx_max_rchg) pfx_max_rchg = dest; chid = UTIL_Get_MSB_Long(fin); /* get chunk id */ chlen = UTIL_Get_MSB_Long(fin); /* get chunk length */ } while(chid == pfx_PARM) { LONG ret; ULONG pnum,res1,res2; PFX_RCHG_HDR *tmp_parm; UBYTE *data; pnum = UTIL_Get_MSB_UShort(fin); /* parm number */ res1 = UTIL_Get_MSB_UShort(fin); /* ??? */ res2 = UTIL_Get_MSB_UShort(fin); /* ??? */ chlen -= 6; data = (UBYTE *)malloc(chlen); if (data == 0) TheEnd1("PFX: parm data malloc failed\n"); ret = fread((char *)(data),1,chlen,fin); if (ret != chlen) TheEnd1("PFX: parm data read failed\n"); DEBUG_LEVEL1 fprintf(stderr,"PARM %lx\n",chlen); DEBUG_LEVEL2 fprintf(stderr," %s\n",data); tmp_parm = PFX_Alloc_RCHG(); tmp_parm->orig = pnum; tmp_parm->dest = res1; tmp_parm->len = chlen; tmp_parm->data = data; if (first_parm == 0) first_parm = cur_parm = tmp_parm; else { cur_parm->next = tmp_parm; cur_parm = tmp_parm; } chid = UTIL_Get_MSB_Long(fin); /* get chunk id */ chlen = UTIL_Get_MSB_Long(fin); /* get chunk length */ } if (chid != pfx_STMT) { fprintf(stderr,"PFX: confused\n"); return(FALSE); } first_fram = cur_fram = 0; frame_count = 0; pfx_rchg_flag = FALSE; while(chlen && !feof(fin) ) { chid = UTIL_Get_MSB_Long(fin); chlen-=4; /* get script id */ if (chid == pfx_A_B) { PFX_PLAY_HDR *p; p = PFX_POP_PLAY_HDR(); if (p == 0) TheEnd1("PFX Play List: stack empty err1\n"); if (pfx_play_temp == 0) TheEnd1("PFX Play List: stack empty err2\n"); DEBUG_LEVEL1 fprintf(stderr,"POP %c%c%c%c\n", ((p->type >> 24) & 0xff), ((p->type >> 16) & 0xff), ((p->type >> 8) & 0xff), ((p->type) & 0xff) ); if (p->type == pfx_REPE) /* point back to just after REPE */ { if (p->loop->next != 0) pfx_play_temp->loop = p->loop->next; else TheEnd1("PFX_Loop: hosed\n"); DEBUG_LEVEL1 fprintf(stderr," loop to %c%c%c%c", ((p->loop->next->type >> 24) & 0xff), ((p->loop->next->type >> 16) & 0xff), ((p->loop->next->type >> 8) & 0xff), ((p->loop->next->type) & 0xff) ); DEBUG_LEVEL1 fprintf(stderr," count=%lx\n",p->loop->next->data); } FREE(p,0x6000); p=0; } else { pfx_play_temp = (PFX_PLAY_HDR *)malloc(sizeof(PFX_PLAY_HDR)); if (pfx_play_temp == 0) TheEnd1("PFX: malloc PFX_PLAY_HDR error\n"); pfx_play_temp->type = chid; pfx_play_temp->data = 0; pfx_play_temp->loop = 0; pfx_play_temp->next = 0; switch(chid) { case pfx_INIT: case pfx_GLOC: case pfx_GLOV: case pfx_REPE: PFX_PUSH_PLAY_HDR(pfx_play_temp); break; case pfx_BITP: case pfx_XDIM: case pfx_YDIM: case pfx_DURA: case pfx_HIGH: case pfx_FLAC: case pfx_COUN: case pfx_INTE: case pfx_AUST: case pfx_SPDU: case pfx_SLWD: pfx_play_temp->data = UTIL_Get_MSB_Long(fin); chlen-=4; PFX_PUSH_PLAY_HDR(pfx_play_temp); break; case pfx_PALL: case pfx_FRAM: case pfx_FILE: pfx_play_temp->data = UTIL_Get_MSB_UShort(fin); chlen-=2; PFX_PUSH_PLAY_HDR(pfx_play_temp); break; default: fprintf(stdout,"PFX read: Unknown STMT chid %lx\n",chid); return(FALSE); break; } } } /* end of while for reading play list */ fclose(fin); /* free up Play List stack just in case it's not already freed up */ { PFX_PLAY_HDR *p; do { p = PFX_POP_PLAY_HDR(); if (p != 0) { FREE(p,0x6000); p=0; fprintf(stderr,"PFX Warning: play list different than expected\n"); } } while(p != 0); } /* loop through play list to create frame list */ pfx_play_lcur = pfx_play_start; while(pfx_play_lcur != 0) { ULONG garb; chid = pfx_play_lcur->type; switch(chid) { case pfx_INIT: case pfx_GLOC: case pfx_GLOV: case pfx_REPE: /* REPEAT: for now must be followed by COUN */ case pfx_FILE: /* NOTE: this is comment only */ break; case pfx_BITP: /* Num of Bitplanes */ pfx_imaged = pfx_play_lcur->data; break; case pfx_XDIM: /* X size */ pfx_imagex = pfx_play_lcur->data; pfx_xflag = TRUE; break; case pfx_YDIM: /* Y size */ pfx_imagey = pfx_play_lcur->data; pfx_yflag = TRUE; break; case pfx_HIGH: /* ??? */ case pfx_FLAC: /* ??? */ case pfx_INTE: /* Interlace flag */ case pfx_AUST: /* don't know */ break; case pfx_DURA: /* ?Duration between frames */ garb = pfx_play_lcur->data; if (garb == 0) garb = 1; pfx_time = garb * PFX_DEFAULT_TIME; break; case pfx_SPDU: /* speed up by this much */ garb = pfx_play_lcur->data; pfx_time += garb * PFX_DEFAULT_TIME; break; case pfx_SLWD: /* slow down by this much */ garb = pfx_play_lcur->data; pfx_time -= garb * PFX_DEFAULT_TIME; if (pfx_time <= 0) pfx_time = 1; break; case pfx_PALL: /* CMAP parm id */ garb = pfx_play_lcur->data; PFX_Setup_CMAP(garb,first_parm); pfx_cflag = TRUE; break; case pfx_COUN: garb = pfx_play_lcur->data; /* 0x3b9ac9ff for example is mouse button */ if (garb >= 0x100) garb = 1; pfx_play_lcur->count = garb; break; case pfx_FRAM: garb = pfx_play_lcur->data; if (first_fram == 0) first_fram = cur_fram = PFX_Alloc_FRAM(); else { cur_fram->next = PFX_Alloc_FRAM(); cur_fram = cur_fram->next; } cur_fram->frame = garb; cur_fram->time = XA_GET_TIME(pfx_time); frame_count++; break; default: fprintf(stdout,"PFX frame lst: Unknown STMT chid %lx\n",chid); return(FALSE); break; } /* end switch */ if ( (pfx_xflag==TRUE) && (pfx_yflag==TRUE) && (pfx_cflag==TRUE) && (pfx_rchg_flag==FALSE)) { pfx_rchg_flag = TRUE; PFX_Extract_Images(anim_hdr,first_rchg,pfx_max_rchg); } if (pfx_play_lcur->loop != 0) { PFX_PLAY_HDR *p; p = pfx_play_lcur->loop; DEBUG_LEVEL2 fprintf(stderr,"PFX frame loop cnt=%lx\n",p->count); p->count--; if (p->count > 0) pfx_play_lcur = p; /* goto COUN */ } pfx_play_lcur = pfx_play_lcur->next; } /* end of while STMT */ /* Free up play list */ { PFX_PLAY_HDR *p; while(pfx_play_start) { p = pfx_play_start; pfx_play_start = pfx_play_start->next; FREE(p,0x6000); p=0; } } { PFX_FRAM_HDR *ptr_fram,*tmp_fram; ULONG i; anim_hdr->frame_lst = (XA_FRAME *)malloc(sizeof(XA_FRAME) * (frame_count + 1)); if (anim_hdr->frame_lst == NULL) TheEnd1("PFX_ANIM: couldn't malloc for frame_lst\0"); DEBUG_LEVEL3 fprintf(stderr,"PFX frame List(%ld): ",frame_count); ptr_fram = first_fram; for(i=0; i<frame_count; i++) { /* frames start at 1, nothing is at 0 */ anim_hdr->frame_lst[i].act = pfx_images[ptr_fram->frame].act; anim_hdr->frame_lst[i].time = ptr_fram->time; DEBUG_LEVEL3 fprintf(stderr,"<%ld>",ptr_fram->frame); tmp_fram = ptr_fram; ptr_fram = ptr_fram->next; FREE(tmp_fram,0x6000); } if (ptr_fram != 0) fprintf(stderr," FRAME stuff: ptr_fram %lx non_zero\n",(ULONG)ptr_fram); DEBUG_LEVEL3 fprintf(stderr,"\n"); anim_hdr->frame_lst[frame_count].time = 0; anim_hdr->frame_lst[frame_count].act = 0; anim_hdr->loop_frame = 0; anim_hdr->last_frame = frame_count - 1; anim_hdr->imagex = pfx_imagex; anim_hdr->imagey = pfx_imagey; anim_hdr->imagec = pfx_imagec; anim_hdr->imaged = pfx_imaged; } { /* FREE PARM STRUCTURES */ PFX_RCHG_HDR *tmp,*tmp1; if (pfx_images != 0) FREE(pfx_images,0x6000); /* free up image structures */ pfx_images=0; tmp = first_parm; while(tmp) { tmp1 = tmp; tmp = tmp->next; FREE(tmp1->data,0x6000); FREE(tmp1,0x6000); } first_parm=0; } return(TRUE); } void PFX_Extract_Images(anim_hdr,first_rchg,pfx_max_rchg) XA_ANIM_HDR *anim_hdr; PFX_RCHG_HDR *first_rchg; ULONG pfx_max_rchg; { ULONG psize,i; UBYTE *data,*pic; PFX_RCHG_HDR *tmp_rchg; psize = pfx_imagex * pfx_imagey; pfx_max_rchg++; /* add 0 up front */ pfx_images = (PFX_RCHG_HDR *)malloc(pfx_max_rchg * sizeof(PFX_RCHG_HDR)); if (pfx_images == 0) TheEnd1("PFX: malloc failed 1\n"); for(i=0; i<pfx_max_rchg;i++) { pfx_images[i].orig = 0; pfx_images[i].data = 0; } pfx_images[0].orig = 1; /* indicate it is used */ tmp_rchg = first_rchg; while(tmp_rchg) { ULONG orig,dest,len; ULONG b_cnt,a_cnt,offset,d,dmask; PFX_RCHG_HDR *tmp1_rchg; orig = tmp_rchg->orig; dest = tmp_rchg->dest; len = tmp_rchg->len; data = tmp_rchg->data; DEBUG_LEVEL2 fprintf(stderr,"PFX Extracting %ld %ld\n",orig,dest); /* new image */ if ( (pfx_images[orig].orig == 0) || (pfx_images[dest].orig == 0 ) ) { pic = (UBYTE *)malloc( XA_PIC_SIZE(psize) ); if (pic == 0) TheEnd1("PFX: malloc failed 2\n"); if (orig == 0) memset((char *)(pic),0x00,psize); else { if (pfx_images[orig].orig == 0) { i = orig; orig = dest; dest = i; } if (pfx_images[orig].orig == 0) { fprintf(stderr,"PFX orig doesn't exist yet. faking it.\n"); memset((char *)(pic),0x00,psize); } else memcpy((char *)(pic),(char *)(pfx_images[orig].data),psize); } dmask = 0x01; while(len) { UBYTE *ptr; b_cnt = (ULONG)(*data++) << 8; b_cnt |= (ULONG)(*data++); len-=2; DEBUG_LEVEL3 fprintf(stderr,"b_cnt = %ld\n",b_cnt); while(len && b_cnt) { offset = (ULONG)(*data++) << 8; offset |= (ULONG)(*data++); len-=2; a_cnt = (ULONG)(*data++) << 8; a_cnt |= (ULONG)(*data++); len-=2; DEBUG_LEVEL4 fprintf(stderr,"<%lx %lx> ",offset,a_cnt); ptr = (UBYTE *)(pic + (offset * 8)); for(i = 0; i <= a_cnt; i++) { d = (ULONG)(*data++) << 8; d |= (ULONG)(*data++); len-=2; IFF_Short_Mod(ptr,d,dmask,1); ptr += pfx_imagex; } b_cnt--; } DEBUG_LEVEL4 fprintf(stderr,"\n\n"); dmask <<= 1; /* move to next bitplane */ } if (b_cnt != 0) fprintf(stderr,"b_cnt nonzero\n"); pfx_images[dest].orig = dest; pfx_images[dest].data = pic; DEBUG_LEVEL2 fprintf(stderr,"New Image pfx_images[deset] = %ld\n",dest); } /* new image */ tmp1_rchg = tmp_rchg; tmp_rchg = tmp_rchg->next; /* move to next image */ FREE(tmp1_rchg->data,0x6000); tmp1_rchg->data=0; FREE(tmp1_rchg,0x6000); tmp1_rchg=0; } /* end of while rchg_hdr's */ for(i=1; i<pfx_max_rchg; i++) { XA_ACTION *act; if (pfx_images[i].data == 0) fprintf(stderr,"ERROR: im not completed\n"); act = ACT_Get_Action(anim_hdr); pfx_images[i].act = act; ACT_Setup_Mapped(act, pfx_images[i].data, pfx_chdr,0,0,pfx_imagex,pfx_imagey,pfx_imagex,pfx_imagey,FALSE,0, TRUE,TRUE,FALSE); ACT_Add_CHDR_To_Action(act,pfx_chdr); } } /* end of function */ void PFX_Setup_CMAP(cmap_id,first_parm) ULONG cmap_id; PFX_RCHG_HDR *first_parm; { ULONG found_flag,i; UBYTE *ptr; PFX_RCHG_HDR *tmp_parm; found_flag = FALSE; tmp_parm = first_parm; while(tmp_parm && (found_flag==FALSE)) { if (tmp_parm->orig == cmap_id) found_flag = TRUE; else tmp_parm = tmp_parm->next; } if (found_flag == FALSE) TheEnd1(stderr,"PFX CMAP: not found\n"); pfx_imagec = tmp_parm->len--; pfx_imagec /= 3; ptr = tmp_parm->data; for(i=0;i<pfx_imagec;i++) { ULONG d; d = (*ptr++) - 48; if (d > 9) d -= 7; /* ascii to integer */ pfx_cmap[i].red = d & 0x0f; d = (*ptr++) - 48; if (d > 9) d -= 7; /* ascii to integer */ pfx_cmap[i].green = d & 0x0f; d = (*ptr++) - 48; if (d > 9) d -= 7; /* ascii to integer */ pfx_cmap[i].blue = d & 0x0f; DEBUG_LEVEL2 fprintf(stderr," %ld) %lx %lx %lx\n", i,pfx_cmap[i].red,pfx_cmap[i].green,pfx_cmap[i].blue); } pfx_chdr = ACT_Get_CMAP(pfx_cmap,pfx_imagec,0,pfx_imagec,0,4,4,4); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.