home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fun CD 26
/
OTACD26.ISO
/
archive
/
game
/
meltyss
/
meltyss.lzh
/
MELTYSS.C
next >
Wrap
C/C++ Source or Header
|
1997-07-07
|
10KB
|
393 lines
/******************************
* メルティランサーBMP変換 *<<Saturn版>>
* Programmed By Melody-Yoshi *
******************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
unsigned char *mem,*bz,tbl[2048],pal[512];
FILE *fp,*fo;
int xwide,ywide,xseek,xpad,bitcode,bitl;
void conv08(char *,int,int,int),conv04(char *,int,int,int);
void writelong(long),writeshort(short);
void outpic(unsigned char *,int),outbmp(unsigned char *,int);
void outbmp16(unsigned char *),reduce(unsigned char *,int);
void wrtlen(int),bitwrite(int,int);
short getshort(unsigned char *,int);
int analyze(char *,int,int);
int decode(void),getlong(unsigned char*,int);
short getshort(unsigned char*,int);
void main(int argc,char *argv[])
{
char fn[48],fz[48];
int i,j,k,m,cnt;
if(argc<2){
printf("meltyss [file] [flag]\n flag:b0|b1|p0|p1\n");exit(1);
}
m=0;strcpy(fn,argv[1]);
mem=(unsigned char *)malloc(0x30000);
bz=(unsigned char *)malloc(0x72000);
if(mem==NULL || bz==NULL){
printf("ナナ:「メモリが足りないわよっ!」\n");exit(1);
}
if(argc>2){
if(argv[2][0]=='p' || argv[2][0]=='P')m=2;
if(argv[2][1]=='1')m|=1;
}
for(i=0;fn[i];i++)if(fn[i]=='.')break;
fn[i]=0;strcpy(fz,fn);strcat(fz,".FAR");
if((fp=fopen(fz,"rb"))==0){
printf("file open error![%s]\n",fz);exit(1);
}
for(fz[i]=0;i>=0;i--)if(fz[i]=='\\' || fz[i]==':')break;
strcpy(fn,&fz[i+1]);fread(tbl,1,0x800,fp);
for(cnt=i=0;;i+=8,cnt++)if(tbl[i]==0 && tbl[i+1]==0 && tbl[i+2]==0 && tbl[i+3]==0)break;
for(i=k=0;i<cnt;i++){
j=getlong(tbl,i<<3)<<11;fseek(fp,(long)j,0);
j=getlong(tbl,(i<<3)+4);fread(mem,1,j,fp);
k=analyze(fn,k,m);
}
fclose(fp);exit(0);
}
int analyze(char *fn,int no,int flag)
{
int adr,cnt,i,j,m,p;
char fz[48],fs[4];
m=decode();p=getshort(bz,6);
if(p!=256 && p!=16){
printf("アンジェラ、エラー見つけちゃったよぉ。\n");exit(1);
}
for(i=0;i<p*2;i++)pal[i]=bz[i+12];
if(strncmp((char *)bz,"SBMP",4)==0){
fs[0]=no/16+'0';if(fs[0]>'9')fs[0]+=7;
fs[1]=(no&15)+'0';if(fs[1]>'9')fs[1]+=7;
strcpy(fz,fn);strcat(fz,fs);
if(flag&2)strcat(fz,".PIC");
else strcat(fz,".BMP");
if((fo=fopen(fz,"wb"))==0){
printf("file create error![%s]\n",fz);exit(1);
}
xwide=getshort(bz,8);ywide=getshort(bz,10);
if(p==256)conv08(fn,no,flag,0x20C);
else if(p==16)conv04(fn,no,flag,0x2C);
fclose(fo);no++;
}
else if(strncmp((char *)bz,"SSP0",4)==0){
cnt=getshort(bz,8);
for(i=0,j=0x20C;i<cnt;i++,j+=8,no++){
fs[0]=no/16+'0';if(fs[0]>'9')fs[0]+=7;
fs[1]=(no&15)+'0';if(fs[1]>'9')fs[1]+=7;
strcpy(fz,fn);strcat(fz,fs);
if(flag&2)strcat(fz,".PIC");
else strcat(fz,".BMP");
if((fo=fopen(fz,"wb"))==0){
printf("file create error![%s]\n",fz);exit(1);
}
xwide=getshort(bz,j);ywide=getshort(bz,j+2);
adr=getlong(bz,j+4);
if(p==256)conv08(fn,no,flag,adr);
else if(p==16)conv04(fn,no,flag,adr);
fclose(fo);
}
}
return(no);
}
int decode(void)
{
int cnt,i,j,k,p,q,dl;
dl=(mem[0]<<16)|(mem[1]<<8)|mem[2];
for(p=6,q=k=0;q<dl;k>>=1){
if((k&0xFF00)==0)k=mem[p++]|0xFF00;
if((k&1)==0)bz[q++]=mem[p++];
else{
j=(mem[p]<<8)|mem[p+1];p+=2;
cnt=(j>>12)&15;if(cnt==15)cnt=mem[p++]+15;
cnt+=3;j=(j&0xFFF)+1;
for(i=0;i<cnt;i++,q++)bz[q]=bz[q-j];
}
}
return(q);
}
void reduce(unsigned char *b,int f)
{
int i,j,m,r1,r2,b1,b2,g1,g2;
unsigned k;
m=xwide*ywide;i=m-2;
if(f==24){
for(j=(m+m+m)/2-3;i>=0;i-=2,j-=3){
m=b[i]<<1;k=pal[m+1]|(pal[m]<<8);
r1=(k&0x1F)<<3;g1=(k&0x3E0)>>2;b1=(k&0x7C00)>>7;
m=b[i+1]<<1;k=pal[m+1]|(pal[m]<<8);
r2=(k&0x1F)<<3;g2=(k&0x3E0)>>2;b2=(k&0x7C00)>>7;
b[j]=(b1+b2)/2;b[j+1]=(g1+g2)/2;b[j+2]=(r1+r2)/2;
}
}
else{
for(;i>=0;i-=2){
m=b[i]<<1;k=pal[m+1]|(pal[m]<<8);
r1=(k&0x1F)<<3;g1=(k&0x3E0)>>2;b1=(k&0x7C00)>>7;
m=b[i+1]<<1;k=pal[m+1]|(pal[m]<<8);
r2=(k&0x1F)<<3;g2=(k&0x3E0)>>2;b2=(k&0x7C00)>>7;
m=(((b1+b2)&0x1F0)<<6)|(((g1+g2)&0x1F0)<<1)|(((r1+r2)&0x1F0)>>4);
b[i]=m&255;b[i+1]=(m>>8);
}
}
xwide/=2;
}
void conv08(char *fn,int no,int flag,int adr)
{
if(flag&2){ /* PIC */
if(flag&1){
reduce(&bz[adr],15);outpic(&bz[adr],15);
}
else outpic(&bz[adr],8);
}
else{ /* BMP */
if(flag&1){
reduce(&bz[adr],24);outbmp16(&bz[adr]);
}
else outbmp(&bz[adr],256);
}
}
void conv04(char *fn,int no,int flag,int adr)
{
int i,j,k;
if(flag){
j=xwide*ywide;
for(j--,i=j*2;i>=0;i-=2,j--){
k=bz[j+adr];bz[i+adr]=k>>4;bz[i+adr+1]=k&15;
}
xwide<<=1;
}
if(flag&2){ /* PIC */
if(flag&1){
reduce(&bz[adr],15);outpic(&bz[adr],15);
}
else outpic(&bz[adr],8);
}
else{ /* BMP */
if(flag&1){
reduce(&bz[adr],24);outbmp16(&bz[adr]);
}
else outbmp(&bz[adr],16);
}
}
/* BMP-FILE OUTPUT */
void outbmp(unsigned char *b,int c)
{
int i;
unsigned short k;
xseek=xwide;xpad=(4-(xseek&3))&3;xseek+=xpad;
fputc('B',fo);fputc('M',fo); /* ID */
writelong((long)c*4L+54L+(long)(xwide+xpad)*(long)ywide); /* FILE SIZE */
writelong(0L); /* RESERVED */
writelong((long)c*4L+54L); /* IMAGE OFFSET */
writelong(40L); /* INFO SIZE */
if(c==256)writelong((long)xwide); /* dx */
else writelong((long)xwide*2L); /* dx */
writelong((long)ywide); /* dy */
writeshort(1); /* PLAIN */
if(c==256)writeshort(8); /* DEPTH */
else writeshort(4);
writelong(0L); /* COMPRESS TYPE */
writelong(0L);
writelong(0L); /* x per meter */
writelong(0L); /* y per meter */
writelong((long)c); /* COLOR */
writelong(0L);
for(i=0;i<c;i++){
k=pal[i*2+1]+(pal[i*2]<<8);
fputc((k&0x7c00)>>7,fo); /* BLUE */
fputc((k&0x3e0)>>2,fo); /* GREEN */
fputc((k&0x1f)<<3,fo); /* RED */
fputc(0,fo);
}
for(i=ywide-1;i>=0;i--){
fwrite(&b[i*xwide],1,xwide,fo);
for(k=0;k<xpad;k++)fputc(0,fo);
}
}
/* WRITE BMP 16*/
void outbmp16(unsigned char *b)
{
int ad,x,y;
unsigned short k;
xseek=xwide*3;xpad=(4-(xseek&3))&3;xseek+=xpad;
fputc('B',fo);fputc('M',fo); /* ID */
writelong(54L+(long)xwide*(long)ywide*3L+(long)xpad*(long)ywide); /* FILE SIZE */
writelong(0L); /* RESERVED */
writelong(54L); /* IMAGE OFFSET */
writelong(40L); /* INFO SIZE */
writelong((long)xwide); /* dx */
writelong((long)ywide); /* dy */
writeshort(1); /* PLAIN */
writeshort(24); /* DEPTH */
writelong(0L); /* COMPRESS TYPE */
writelong(0L);
writelong(0L); /* x per meter */
writelong(0L); /* y per meter */
writelong(0L);
writelong(0L);
for(y=ywide-1;y>=0;y--){
fwrite(&b[y*xwide*3],1,xwide*3,fo);
for(x=0;x<xpad;x++)fputc(0,fo);
}
}
/* PIC-FILE OUTPUT */
void outpic(unsigned char *b,int cbit)
{
int a,ad,c,d,i,p,x,y,xx,yy,r1,g1,b1;
struct{
int c,n,p;
}table[128];
if(cbit==8){
r1=xwide*ywide;
for(i=r1-1,p=r1+r1-2;i>=0;i--,p-=2){
c=b[i]<<1;b[p]=(c&256)>>8;b[p+1]=c&255;
}
}
else{
for(p=0;p<xwide*ywide*2;p+=2){
i=b[p]+(b[p+1]<<8);
r1=(i&0x1f)<<6;g1=(i&0x3E0)<<6;b1=(i&0x7C00)>>9;
i=g1|r1|b1;b[p]=i/256;b[p+1]=i&255;
}
}
bitl=bitcode=0;
for(i=0;i<128;i++){
table[i].c=0;table[i].p=i+1;table[i].n=i-1;
}
table[127].p=0;table[0].n=127;
fprintf(fo,"PIC/MM/XSS:"); /* HEADER */
fputc(26,fo);fputc(0,fo); /* TEXT EOF */
fputc(0,fo);fputc(0,fo); /* MODE */
fputc(0,fo);fputc(cbit,fo); /* COLOR LENGTH */
fputc(xwide/256,fo);fputc(xwide&255,fo); /* SIZE X */
fputc(ywide/256,fo);fputc(ywide&255,fo); /* SIZE Y */
if(cbit==8){
for(i=0;i<256;i++){
r1=pal[(i<<1)+1]|(pal[i<<1]<<8);
b1=(r1&0x7C00)>>7;g1=(r1&0x3E0)>>2;r1=(r1&0x1F)<<3;
r1=(g1<<8)|(r1<<3)|(b1>>2);
fputc(r1/256,fo);fputc(r1&255,fo);
}
}
for(p=y=c=0;y<xwide*ywide*2;y+=2){
if((i=((b[y]<<8)|(b[y+1]))&0xFFFE)!=c){
c=i;b[y]=c>>8;b[y+1]=(c&255)|1;
}
}
for(i=y=0;y<ywide;y++){
for(ad=y*xwide*2,x=0;x<xwide;x++,ad+=2){
i++;
if((c=(b[ad]<<8)|(b[ad+1]))&1){
wrtlen(i);
if(cbit==8)bitwrite(8,c>>1);
else{
for(a=0;a<128;a++)if(table[a].c==(c&0xFFFE))break;
if(a==128){
p=table[p].p;table[p].c=c&0xFFFE;
}
else{
if(p!=a){
table[table[a].p].n=table[a].n;
table[table[a].n].p=table[a].p;
table[table[p].p].n=a;table[a].p=table[p].p;
table[p].p=a;table[a].n=p;p=a;
}
}
if(a!=128)bitwrite(8,a+128);
else bitwrite(16,(unsigned)c/2);
}
for(a=0,xx=x,yy=y+1,r1=((y+1)*xwide+x)*2;yy<ywide;yy++,r1+=xwide*2){
if(c==((b[r1]<<8)|(b[r1+1])))d=2;
else{
xx--;r1-=2;
if(xx>=0 && c==((b[r1]<<8)|(b[r1+1])))d=1;
else{
xx+=2;r1+=4;
if(xx<xwide && c==((b[r1]<<8)|(b[r1+1])))d=3;
else{
xx-=3;r1-=6;
if(xx>=0 && c==((b[r1]<<8)|(b[r1+1])))d=4;
else{
xx+=4;r1+=8;
if(xx<xwide && c==((b[r1]<<8)|(b[r1+1])))d=5;
else break;
}
}
}
}
b[r1]=c>>8;b[r1+1]=c&0xFE;
if(a==0)bitwrite(1,1);
if(d==4)bitwrite(4,2);
if(d==5)bitwrite(4,3);
if(d<=3)bitwrite(2,d);
a=1;
}
if(a==0)bitwrite(1,0);
else bitwrite(3,0);
b[ad]=c>>8;b[ad+1]=c&0xFE;i=0;
}
}
}
wrtlen(i+1);bitwrite(8,0);bitwrite(31,0);
}
/* WRITE SHORT VALUE */
void writeshort(short n)
{
fputc(n&255,fo);fputc((n>>8)&255,fo);
}
/* WRITE LONG VALUE */
void writelong(long n)
{
fputc((int)(n&255),fo);n/=256L;
fputc((int)(n&255),fo);n/=256L;
fputc((int)(n&255),fo);n/=256L;
fputc((int)(n&255),fo);
}
void wrtlen(int n)
{
int a,b;
a=1;b=4;
while(n>b-2){
a++;b<<=1;
}
bitwrite(a,0xfffffffe);bitwrite(a,(n+1-b/2));
}
void bitwrite(int sz,int n)
{
int i;
if(bitl+sz>32){
i=32-bitl;bitl+=sz-32;
bitcode=(bitcode<<i)|((n>>bitl)&((1<<i)-1));
fputc(bitcode>>24,fo);
fputc((bitcode>>16)&255,fo);
fputc((bitcode>>8)&255,fo);
fputc(bitcode&255,fo);
bitcode=n&((1<<bitl)-1);
}
else if(bitl+sz==32){
bitcode=(bitcode<<sz)|(n&((1<<sz)-1));bitl=0;
fputc(bitcode>>24,fo);
fputc((bitcode>>16)&255,fo);
fputc((bitcode>>8)&255,fo);
fputc(bitcode&255,fo);
}
else{
bitcode=(bitcode<<sz)|(n&((1<<sz)-1));bitl+=sz;
}
}
/* READ LONG VALUE */
int getlong(unsigned char *b,int p)
{
int i;
i=b[p]<<24;i|=b[p+1]<<16;i|=b[p+2]<<8;i|=b[p+3];return(i);
}
/* READ SHORT VALUE */
short getshort(unsigned char *b,int p)
{
short i;
i=b[p]<<8;i|=b[p+1];return(i);
}