ReC98/zuncom/zungen.c

140 lines
2.8 KiB
C
Raw Normal View History

#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <dir.h>
#include "zuncom/common.h"
int readline(char *path, size_t size, FILE* fl) {
char *pathp;
if(!fgets(path, size, fl)) return 1;
if(*path) {
pathp = path+strlen(path)-1;
if(*pathp == '\n') *pathp = '\0';
}
return 0;
}
#define MAX_COUNT 32
#define DATA_SIZE (2+MAX_COUNT*10+2+3)
int main(int argc, char** argv) {
static char path[MAXPATH+1];
static char names[8*MAX_COUNT];
static int entries[MAX_COUNT+1];
FILE *fl, *fo;
int count;
int size, stubsize;
int pathpos;
int i,j;
int errval;
if(argc != 5) {
printf("Usage: zungen zun_stub.bin moveup.bin listfile.txt outfile.bin\n");
return 1;
}
fl = fopen(argv[3],"r");
if(!fl) {
printf("Error: couldn't open listfile: %s\n", strerror(errno));
return 2;
}
fo = fopen(argv[4],"wb");
if(!fo) {
fclose(fl);
printf("Error: couldn't open outfile: %s\n", strerror(errno));
return 3;
}
/* read proc count */
if(readline(path, sizeof(path), fl)) {
errval = 4; goto err;
}
count = atoi(path);
if(count < 0 || count > MAX_COUNT) {
printf("Error: count is too big!\n");
errval = 5; goto err;
}
/* write stub and proc count */
append(argv[1], fo);
fputw(count, fo);
/* read proc names */
memset(names, ' ', sizeof(names));
for(i=0;i<count;i++) {
if(readline(path, sizeof(path), fl)) {
errval = 6; goto err;
}
for(j=0;j<8;j++) {
if(path[j] == 0) {
break;
}
names[j+i*8] = path[j];
}
}
/* write proc names */
if(sizeof(names) != fwrite(names, 1, sizeof(names), fo)) {
printf("Error: write error\n");
errval = 7; goto err;
}
/* save list file position for later */
pathpos = ftell(fl);
/* calc offset of first entry */
stubsize = size = filesize(argv[1]);
if(size == -1) {
errval = 8; goto err;
}
size += DATA_SIZE + 0x100;
/* build entry table */
memset(entries, 0, sizeof(entries));
for(i=0;i<count;i++) {
entries[i] = size;
if(readline(path, sizeof(path), fl)) {
errval = 9; goto err;
}
j = filesize(path);
if(j == -1) { errval = 10; goto err; }
size += j;
}
entries[i] = size;
/* write entry table */
if(sizeof(entries) != fwrite(entries, 1, sizeof(entries), fo)) {
printf("Error: write error\n");
errval = 11; goto err;
}
/* write moveup_indirect */
fputc('\xE8', fo); /* call rel16 */
fputw(size - (stubsize + DATA_SIZE + 0x100), fo);
/* append com files */
fseek(fl, pathpos, SEEK_SET);
for(i=0;i<count;i++) {
if(readline(path, sizeof(path), fl)) {
errval = 12; goto err;
}
if(append(path, fo)) {
errval = 13; goto err;
}
}
/* append moveup */
if(append(argv[2], fo)) {
errval = 14; goto err;
}
fclose(fl);
if(fclose(fo)) {
printf("Error: unsuccessful close\n");
return 15;
}
return 0;
err:
fclose(fl);
fclose(fo);
return errval;
}