aboutsummaryrefslogtreecommitdiff
path: root/devtools/create_supernova/create_image/create_image.cpp
blob: 6f71a0c440a2362d3b6875401a40e464f7a4b240 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstring>
#include <iomanip>
#include <cstdlib>

std::string filenumber;

int writePalette(std::ofstream &output) {
	std::string filename = filenumber + "/palette";
	std::ifstream palette(filename.c_str());
	if (!palette.is_open()) {
		std::cerr << "Couldn't open palette file" << std::endl;
		return 1;
	}
	int input;
	do {
		palette >> input;
		if (palette.eof())
			break;
		output << (char) input;
	} while(true);
	palette.close();
	return 0;
}

int writeSections(std::ofstream &output) {
	std::string filename = filenumber + "/section_info";
	std::ifstream sectionInfo(filename.c_str());
	if (!sectionInfo.is_open()) {
		std::cerr << "Couldn't open section_info file" << std::endl;
		return 0;
	}
	int numSections;
	sectionInfo >> numSections;
	output << (char) numSections;

	int input;
	char *input_byte = (char *) &input;
	for(int i = 0; i < numSections; i++) {
		//x1
		sectionInfo >> input;
		output << (char)input_byte[0];
		output << (char)input_byte[1];
		//x2
		sectionInfo >> input;
		output << (char)input_byte[0];
		output << (char)input_byte[1];
		//y1
		sectionInfo >> input;
		output << (char)input;
		//y2
		sectionInfo >> input;
		output << (char)input;
		//next
		sectionInfo >> input;
		output << (char)input;
		//addressLow
		sectionInfo >> input;
		output << (char)input_byte[0];
		output << (char)input_byte[1];
		//addressHigh
		sectionInfo >> input;
		output << (char)input;
	}
	sectionInfo.close();
	return numSections;
}

int writeClickFields(std::ofstream &output) {
	std::string filename = filenumber + "/clickfield_info";
	std::ifstream clickFieldInfo(filename.c_str());
	if (!clickFieldInfo.is_open()) {
		std::cerr << "Couldn't open clickfield_info file" << std::endl;
		return 1;
	}
	int numClickFields;
	clickFieldInfo >> numClickFields;
	output << (char) numClickFields;

	int input;
	char *input_byte = (char *) &input;
	for(int i = 0; i < numClickFields; i++) {
		//x1
		clickFieldInfo >> input;
		output << (char)input_byte[0];
		output << (char)input_byte[1];
		//x2
		clickFieldInfo >> input;
		output << (char)input_byte[0];
		output << (char)input_byte[1];
		//y1
		clickFieldInfo >> input;
		output << (char)input;
		//y2
		clickFieldInfo >> input;
		output << (char)input;
		//next
		clickFieldInfo >> input;
		output << (char)input;
	}
	clickFieldInfo.close();
	return 0;
}

int writePixelData(std::ofstream &output, int imageNum, int skip) {
	std::ostringstream fileName;
	fileName << filenumber << "/image" << imageNum << ".bmp";
	std::ifstream image(fileName.str().c_str(), std::ios::binary);
	if (!image.is_open()) {
		std::cerr << "Couldn't open " << fileName.str() << " file" << std::endl;
		return 0;
	}

	image.seekg(0, image.end);
	int length = image.tellg();
	length -= skip;
	image.seekg(skip, image.beg);
	char *buf = new char[length];
	image.read(buf, length);
	output.write(buf, length);
	delete[] buf;
	return length;
}

void printHelp() {
	std::cout << "create_image output-prefix file-number bytes-skip" << std::endl << std::endl;
	std::cout << "	output-prefix: String the created file should begin with" << std::endl;
	std::cout << "	file-number: Number of the created file and also name of source folder" << std::endl;
	std::cout << "	bytes-skip: How many bytes to to skip in each .bmp file" << std::endl;
	std::cout << std::endl << "EXAMPLE:" << std::endl
		<< "create_image ms2_data 15 1146" << std::endl
		<< "	creates ms2_data.015 assuming there are the right files inside 015 folder" << std::endl;
}

int main(int argc, char *argv[]) {
	if (argc == 2 && !strcmp(argv[1], "--help")) {
		printHelp();
		return 0;
	}
	if (argc != 4 ) {
		printHelp();
		return 1;
	}
	std::ostringstream oss;
	oss << std::setfill('0') << std::setw(3) << argv[2];
	filenumber = oss.str();
	char *ptr;
	int bytesSkip = strtol(argv[3], &ptr, 10);
	std::string oFileName = argv[1];
	oFileName += "." + filenumber;
	std::ofstream output(oFileName.c_str(), std::ios::binary);
	if (!output.is_open()) {
		std::cerr << "Couldn't open output file" << std::endl;
		return 1;
	}
	// size
	// just a place holder, will be filled later
	output << (char) 0x40;
	output << (char) 0x70;
	output << (char) 0x01;
	output << (char) 0x00;
	if (writePalette(output))
		return 1;
	int numImages = writeSections(output);
	if (numImages == 0)
		return 1;
	if (writeClickFields(output))
		return 1;
	// we don't compress the images, so set to 0
	output << (char) 0; //numRepeat
	output << (char) 0; //numZw
	int totalLength = 0;
	int oldLength = 0;
	for (int i = 0; i < numImages; i++) {
		totalLength += writePixelData(output, i, bytesSkip);
		if (oldLength == totalLength) {
			std::cerr << "Error while reading the image number: " << i << std::endl; 
			return 1;
		}
		oldLength = totalLength;
	}

	//reversing the size computation inside the engine
	totalLength += 15;
	totalLength /= 16;
	totalLength -= 0x70;
	int i = (totalLength & 0xf000) >> 12;
	int j = totalLength << 4;
	char *i_p = (char *) &i;
	char *j_p = (char *) &j;

	//writing the size
	output.seekp(0);
	output << j_p[0];
	output << j_p[1];
	output << i_p[0];
	output << i_p[1];
	output.close();
	return 0;
}