7 #define ADS ":::AGSalphahack " VERSION " by rofl0r:::"
9 static int usage(char *argv0
) {
10 fprintf(stderr
, ADS
"\nusage:\n%s [-s spriteno] DIR\n"
11 "removes alphachannel flag from specified sprite in game file.\n"
12 "if spriteno is -1 (default), all flags are removed.\n"
13 "gamefile is typically ac2game.dta or game28.dta inside DIR.\n"
14 "this is useful when sprites have been hacked/converted to 16bit.\n"
15 "you should make a backup of the file before doing this.\n"
20 #define SPF_ALPHACHANNEL 0x10
22 int main(int argc
, char**argv
) {
23 int c
, flags
= 0, spriteno
= -1;
24 while ((c
= getopt(argc
, argv
, "s:")) != EOF
) switch(c
) {
25 case 's': spriteno
= atoi(optarg
); break;
26 default: return usage(argv
[0]);
28 if(!argv
[optind
]) return usage(argv
[0]);
29 char *dir
= argv
[optind
];
33 if(!ADF_find_datafile(dir
, fnbuf
, sizeof(fnbuf
)))
36 enum ADF_open_error aoe
= ADF_open(a
, fnbuf
);
37 if(aoe
!= AOE_success
&& aoe
<= AOE_gamebase
) {
38 fprintf(stderr
, "failed to open/process data file: %s\n", AOE2str(aoe
));
40 } else if (aoe
!= AOE_success
) {
41 fprintf(stderr
, "warning: failed to process some non-essential parts (%s) of gamefile, probably from a newer game format\n", AOE2str(aoe
));
44 off_t off
= ADF_get_spriteflagsstart(a
);
45 unsigned nsprites
= ADF_get_spritecount(a
);
48 printf("removing alpha of %u out of %u spriteflags.\n", spriteno
==-1?nsprites
:1, nsprites
);
50 FILE *f
= fopen(fnbuf
, "r+b");
52 fseeko(f
, off
, SEEK_SET
);
53 unsigned char *buf
= malloc(nsprites
);
54 fread(buf
, 1, nsprites
, f
);
57 for(i
=0;i
<nsprites
;++i
) {
58 if(spriteno
== -1 || spriteno
== i
)
59 buf
[i
] = buf
[i
] & (~SPF_ALPHACHANNEL
);
61 fseeko(f
, off
, SEEK_SET
);
62 fwrite(buf
, 1, nsprites
, f
);