9 * Another World game data unpacker
10 * Only DOS version are supported
13 #define MAX_MEMINFO 256
14 #define MSG_OPENERR "can't open file %s.\n"
15 #define MSG_WRITEERR "can't create file %s.\n"
16 #define MSG_UNPKERR "error while unpack file %s.\n"
18 struct __attribute__ ((__packed__
)) memrec
{
32 struct memrec meminfo
[MAX_MEMINFO
];
36 uint32_t size
, datasize
;
37 uint32_t start
, idx
, oidx
;
40 uint32_t pkint(int adr
) {
41 return ((pk
[adr
]) << 24) |
42 ((pk
[adr
+ 1]) << 16) |
43 ((pk
[adr
+ 2]) << 8) |
66 int getCode(int numChunks
) {
76 void decUnk1(int numChunks
, int addCount
) {
77 int count
= getCode(numChunks
) + addCount
+ 1;
80 pk
[oidx
] = getCode(8);
85 void decUnk2(int numChunks
) {
86 int i
= getCode(numChunks
);
90 pk
[oidx
] = pk
[oidx
+ i
];
97 datasize
= pkint(idx
);
99 oidx
= start
+ datasize
- 1;
127 } while(datasize
> 0);
133 struct memrec
*r
= &meminfo
[i
];
136 char *nnum
= (r
->bank
<= 0xF)?"0":"";
137 snprintf(name
, 64, "BANK%s%X", nnum
, r
->bank
);
139 if((fp
= fopen(name
, "r")) == NULL
) {
140 printf(MSG_OPENERR
, name
);
144 pk
= malloc(r
->size
);
146 fseek(fp
, r
->offset
, SEEK_SET
);
147 fread(pk
, r
->pksize
, 1, fp
);
150 if(r
->pksize
== r
->size
) {
154 idx
= start
+ r
->pksize
- 4;
162 printf("NUM STATE TYPE BANK OFFSET PKSIZE SIZE\n");
164 while(count
< MAX_MEMINFO
) {
165 struct memrec
*r
= &meminfo
[count
];
166 fread(r
, sizeof(struct memrec
), 1, fp
);
167 r
->offset
= ntohl(r
->offset
);
168 r
->pksize
= ntohs(r
->pksize
);
169 r
->size
= ntohs(r
->size
);
170 printf("%3i %5u %4u %4X %8X %6u %5u\n", count
, r
->state
, r
->type
,
171 r
->bank
, r
->offset
, r
->pksize
, r
->size
);
180 int main(int argc
, char **argv
) {
181 if((fp
= fopen("MEMLIST.BIN", "r")) == NULL
) {
182 printf(MSG_OPENERR
, "MEMLIST.BIN");
190 for(int i
= 0; i
< count
- 1; i
++) {
194 switch(meminfo
[i
].type
) {
204 case 3: /* palette */
210 case 5: /* polygons */
218 snprintf(name
, 64, "file%i.%s", i
, ext
);
221 printf(MSG_UNPKERR
, name
);
225 if((fp
= fopen(name
, "w")) == NULL
) {
226 printf(MSG_WRITEERR
, name
);
230 fwrite(pk
, meminfo
[i
].size
, 1, fp
);