aboutsummaryrefslogtreecommitdiff
path: root/devtools/create_mads/main.cpp
blob: 26ae2a7558de59aaae8a863bdb4cc29b5ffc0f1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *
 */

// HACK to allow building with the SDL backend on MinGW
// see bug #1800764 "TOOLS: MinGW tools building broken"
#ifdef main
#undef main
#endif // main

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"

#define BUFFER_SIZE 8192

void link(const char *destFilename, char **srcFilenames, int srcCount) {
	if (srcCount <= 0)
		return;

	FILE *destFile = fopen(destFilename, "wb");
	if (!destFile)
		return;
	unsigned int v = 0;
	const char *headerStr = "MADS";
	int fileOffset = 4 * (srcCount + 2);

	// Write header bit
	fwrite(headerStr, 1, 4, destFile);
	for (int i = 0; i <= srcCount; ++i)
		fwrite(&v, 1, 4, destFile);
	
	// Set up buffer for copying
	void *tempBuffer = malloc(BUFFER_SIZE);

	// Loop through copying each source file and setting it's file offset in the header
	for (int i = 0; i < srcCount; ++i) {
		// Add any extra padding to ensure that each file starts on a paragraph boundary
		if ((fileOffset % 16) != 0) {
			v = 0;
			while ((fileOffset % 16) != 0) {
				fwrite(&v, 1, 1, destFile);
				++fileOffset;
			}
		}

		FILE *srcFile = fopen(srcFilenames[i], "rb");
		if (!srcFile) {
			printf("Could not locate file '%s'\n", srcFilenames[i]);
			break;
		}

		// Set the starting position of the file
		fseek(destFile, 4 + (i * 4), SEEK_SET);
		fwrite(&fileOffset, 1, 4, destFile);

		// Move back to the end of the destination and copy the source file contents over
		fseek(destFile, 0, SEEK_END);
		while (!feof(srcFile)) {
			int bytesRead = fread(tempBuffer, 1, BUFFER_SIZE, srcFile);
			fwrite(tempBuffer, 1, bytesRead, destFile);
			fileOffset += bytesRead;
		}

		fclose(srcFile);
	}

	fclose(destFile);
	free(tempBuffer);
	printf("Done.\n");
}

int main(int argc, char *argv[]) {
	if (argc == 1) {
		printf("%s - ScummVM MADS Game script compiler v 1.0\n\n", argv[0]);
		printf("Parameters: %s src_filename.txt [dest_filename.bin] - Compiles a script text file to an output binary\t", argv[0]);
		printf("\t%s /link mads.dat filename1.bin [filename2.bin ..] - Joins one or more compiled Bin files to make\n", argv[0]);
		printf("an output suitable for running in ScummVM.\n\n");
	} else if (!strcmp(argv[1], "/link")) {
		// Link intermediate files into a final mads.dat file
		if (argc < 4)
			printf("Insufficient parameters\n");
		else
			link(argv[2], &argv[3], argc - 3);

	} else {
		// Compile a file
		char buffer[256];
		const char *destFilename = buffer;
		if (argc >= 3)
			destFilename = argv[2];
		else {
			// Use the source filename, but change the extension to '.bin'
			strcpy(buffer, argv[1]);
			char *p = buffer + strlen(buffer) - 1;
			while ((p >= buffer) && (*p != '.')) --p;
			if (p > buffer)
				// Change the extension
				strcpy(p, ".bin");
		}
		
		// Compile the specified source file
		bool result = Compile(argv[1], destFilename);
		return result ? 0 : 1;
	}

	return 0;
}