Subversion Repositories spk

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#include "bob_dom_cut.h"
2
#include "../common/indian.h"
3
 
4
static int g_i;
5
#define BOB_WRITE(fd, i) (g_i=be2le((unsigned int)i), write(fd, &g_i, sizeof(i)))
6
 
7
#define max(a, b) (a > b ? a : b)
8
//---------------------------------------------------------------------------------
9
bool bob_dom_name::toFile(bob_dom_otextfilestream& os)
10
{
11
	if(m_text && *m_text!=0) {
12
		int oldf=os.flags();
13
		os << noSemicolons << "N " << autoSemicolons << m_text;
14
		os.flags(oldf);
15
	}
16
	return os.good();
17
}
18
//---------------------------------------------------------------------------------
19
// STAT
20
#ifdef X2BC_USE_INI_FORMATS
21
bool bob_dom_stat::load(bob_dom_ibinaryfilestream& is, const Settings *settings)
22
{
23
	is >> frameId;
24
	m_format=settings->findStatFormat(frameId);
25
	if(m_format==NULL){
26
		error(s_error, e_format_noStatFormat, "Cannot find STAT format 0x%X", frameId);
27
		setstate(bob_dom_stat::noFormat);
28
	}
29
	else{
30
		int v;
31
		for(Settings::StatFormat::const_iterator &it=m_format->tokens.begin(); it!=m_format->tokens.end(); ++it){
32
			for(int i=0; i < it->count; i++){
33
				is >> v;
34
				push_back(v);
35
			}
36
			if(is.fail()){
37
				error(s_error, e_format_notEnoughData, "Not enough data to match format 0x%X", frameId);
38
				setstate(cannotMatchFormat);
39
				break;
40
			}
41
		}
42
	}
43
	return rdstate()==formatted;
44
}
45
//---------------------------------------------------------------------------------
46
bool bob_dom_stat::toFile(bob_dom_obinaryfilestream& os)
47
{
48
	os << frameId;
49
	for(iterator &it=begin(); it!=end(); ++it){
50
		os << *it;
51
	}
52
	return os.good();
53
}
54
//---------------------------------------------------------------------------------
55
bool bob_dom_stat::toFile(bob_dom_otextfilestream& os, const Settings *settings)
56
{
57
	os << noSemicolons;
58
	if(rdstate()!=formatted && settings->outputWarnings()){
59
		os << "// Error: STAT frame id=" << hex << "0x" << frameId << dec;
60
		if(rdstate()==noFormat)	
61
			os << ": cannot find frame format";
62
		else
63
			os << ": unable to match frame format";
64
	}
65
	else{
66
		if(settings->statFormatWarnings() && settings->outputWarnings() && m_format->issueWarning)
67
			os << "// Warning: Format 0x" << hex << m_format->id << " was used and it's marked with warning sign" << endl;
68
 
69
		double val;
70
		os << "{ ";
71
 
72
		os << hex << "0x" << frameId << "; " << dec;
73
 
74
		iterator &valit=begin();
75
 
76
		for(Settings::StatFormat::const_iterator &it=m_format->tokens.begin(); it!=m_format->tokens.end(); ++it){
77
			for(int i=0; i < it->count; i++){
78
				val=*valit;
79
				if(settings->convert())
80
					val*=it->numFormat->multiplier;
81
				if(settings->convert() && it->numFormat->outformat==Settings::NumberFormat::Float)
82
					os << (float)val;
83
				else
84
					os << (int)val;
85
 
86
				os << ';';
87
 
88
				++valit;
89
			}
90
			if(it->data)
91
				os << it->data;
92
		}
93
 
94
		os << noSemicolons << " }";
95
	}
96
	return os.good();
97
}
98
//---------------------------------------------------------------------------------
99
#endif // defined(X2BC_USE_INI_FORMATS)
100
 
101
// PATH
102
bool bob_dom_path::load(bob_dom_ibinaryfilestream& is, int version)
103
{
104
	int hdr;
105
	is >> hdr;
106
	if(hdr!=hdr_begin){
107
		error(e_badHeader);
108
		return false;
109
	}
110
	is >> partIdx;
111
	if(version < 6) {
112
		int bid;
113
		is >> bid;
114
		m_bodyId=new char[20];
115
		_itoa(bid, m_bodyId, 10);
116
	}
117
	else 
118
		is >> m_bodyId;
119
 
120
	is >> cockpitIdx >> parentIdx >> bodyFlags;
121
 
122
	if(peek(is)==bob_dom_name::hdr_begin){
123
		if(name.load(is)==false){
124
			for(ErrorIterator &it=name.errors.begin(); it!=name.errors.end(); ++it){
125
				error(it->code, "name: %s", it->text);
126
			}
127
			return false;
128
		}
129
	}
130
 
131
	if(peek(is)==bob_dom_constants::hdr_begin){
132
		if(constants.load(is)==false){
133
			for(ErrorIterator &it=name.errors.begin(); it!=name.errors.end(); ++it){
134
				error(it->code, "constants: %s", it->text);
135
			}
136
			return false;
137
		}
138
	}
139
 
140
	if(peek(is)==bob_dom_bob::hdr_begin){
141
		bob=new bob_dom_bob(m_settings);
142
		if(bob->load(is)==false){
143
			for(ErrorIterator &it=bob->errors.begin(); it!=bob->errors.end(); ++it){
144
				error(it->code, "bob->%s", it->text);
145
			}
146
			return false;
147
		}
148
	}
149
	int noteLineCount;
150
	is >> noteLineCount;
151
	if(noteLineCount > 0){
152
		if(m_notes.load(is, noteLineCount)==false){
153
			for(ErrorIterator &it=m_notes.errors.begin(); it!=m_notes.errors.end(); ++it){
154
				error(it->code, "notes->%s", it->text);
155
			}
156
			return false;
157
		}
158
	}
159
 
160
	int statCount;
161
	is >> statCount;
162
	if(loadStatValues(is, statCount)==false) return false;
163
 
164
	is >> hdr;
165
	if(is.fail())
166
		error(e_notEnoughData);
167
	else if(hdr!=hdr_end)
168
		error(e_badEndHeader);
169
 
170
	/////////////////
171
	//if(hdr==hdr_end) formatStats();
172
	////////////////
173
	return hdr==hdr_end && !is.fail();
174
}
175
//---------------------------------------------------------------------------------
176
bool bob_dom_path::loadStatValues(bob_dom_ibinaryfilestream& is, int count)
177
{
178
	int hdr;
179
	is >> hdr;
180
	if(hdr!=hdr_stat_begin){
181
		error(e_badHeader, "Expected STAT header.");
182
		return false;
183
	}
184
 
185
	child_type *ch;
186
	bool bRes;
187
 
188
	for(int i=0; i < count; i++){
189
		ch=createChild();
190
#ifdef X2BC_USE_INI_FORMATS
191
		bRes=ch->load(is, m_settings);
192
#else
193
		bRes=ch->load(is);
194
#endif
195
		for(ErrorIterator &it=ch->errors.begin(); it!=ch->errors.end(); ++it){
196
			error(it->severity, it->code, "stat->frame[%d]: %s", i, it->text);
197
		}
198
		if(bRes==false) break;
199
	}
200
 
201
	is >> hdr;
202
	if(hdr!=hdr_stat_end){
203
		error(s_error, e_moreData, "More data in STAT section than expected - skipping");
204
		do{
205
			is >> hdr;
206
		}
207
		while(hdr!=hdr_stat_end && is.good());
208
	}
209
 
210
	if(hdr!=hdr_stat_end)
211
		error(e_notEnoughData);
212
	return hdr==hdr_stat_end;
213
}
214
//---------------------------------------------------------------------------------
215
bool bob_dom_path::toFile(bob_dom_obinaryfilestream& os, int cutVersion)
216
{
217
	os << hdr_begin;
218
	os << partIdx;
219
	if(cutVersion >= 6)
220
		os << bodyId();
221
	else
222
		os << atoi(bodyId());
223
 
224
	os << cockpitIdx;
225
	os << parentIdx;
226
	os << bodyFlags;
227
	os << name;
228
	constants.toFile(os);
229
	if(bob) bob->toFile(os);
230
	os << (int)m_notes.size();
231
	m_notes.toFile(os);
232
	os << (int)size();
233
 
234
	os << hdr_stat_begin;
235
	for(iterator &it=begin(); it!=end(); ++it){
236
		it->toFile(os);
237
	}
238
	os << hdr_stat_end << hdr_end;
239
	return true;
240
}
241
//---------------------------------------------------------------------------------
242
bool bob_dom_path::toFile(bob_dom_otextfilestream& os, int idx)
243
{
244
	os << noSemicolons << "P " << partIdx << "; B " << bodyId() << "; ";
245
	if(parentIdx!=-1)
246
		os << "F " << parentIdx << "; ";
247
 
248
	if(cockpitIdx > 0)
249
		os << "C " << cockpitIdx << "; ";
250
 
251
	os << name;
252
 
253
	constants.toFile(os);
254
 
255
	/*
256
		we've got old x2 flags and new x3 flags
257
		these 2 can be mixed together
258
 
259
		for example body || light
260
 
261
		only the body (64) and scene (128) can be mixed with anything else imho
262
	*/
263
	if(bodyFlags!=0) {
264
		if(bodyFlags & BodyFlags::fBody)
265
			os << "b ";
266
		if(bodyFlags & BodyFlags::fScene)
267
			os << "j ";
268
		int i=bodyFlags & 0x3F;
269
		if(i) 
270
			os << (char) ('b' + i) << ' ';
271
	}
272
 
273
	os << "// idx " << idx << ", flags: " << bodyFlags << endl;
274
 
275
	if(m_notes.size())
276
		m_notes.toFile(os);
277
 
278
	if(bob){
279
		os << noSemicolons << "L { // beginning of embedded BOB" << endl;
280
		os << *bob << "} // end of embedded BOB" << endl << endl;
281
	}
282
 
283
	int i=0;
284
	for(iterator &it=begin(); it!=end(); ++it, ++i){
285
#ifdef X2BC_USE_INI_FORMATS
286
		it->toFile(os, m_settings);
287
#else
288
		it->toFile(os);
289
#endif
290
		os << " // " << i << endl;
291
	}
292
	os << endl;
293
 
294
	return os.good();
295
}
296
//---------------------------------------------------------------------------------
297
// CUT file
298
bool bob_dom_cut::load(bob_dom_ibinaryfilestream& is)
299
{
300
	int hdr;
301
	is >> hdr;
302
	if(hdr!=hdr_begin){
303
		error(e_badHeader);
304
		return false;
305
	}
306
 
307
	if(peek(is)==bob_dom_info::hdr_begin){
308
		if(!info.load(is)){
309
			for(ErrorIterator &it=info.errors.begin(); it!=info.errors.end(); ++it){
310
				error(it->code, "info: %s", it->text);
311
			}
312
			return false;
313
		}
314
	}
315
 
316
	is >> version;
317
 
318
	if(version!=supported_version)
319
		error(s_warning, e_badVersion, "Unsupported CUT1 version, loading might fail");
320
 
321
	is >> m_storedPathCount;
322
 
323
	child_type *ch;
324
	for(int i=0; i < m_storedPathCount; i++){
325
		ch=createChild();
326
		bool bRes=ch->load(is, version);
327
		for(ErrorIterator &it=ch->errors.begin(); it!=ch->errors.end(); ++it){
328
			error(it->code, "path[%d]->%s", i, it->text);
329
		}
330
		if(bRes==false) return false;
331
	}
332
 
333
	is >> hdr;
334
	if(hdr!=hdr_end)
335
		error(e_badEndHeader);
336
	return hdr==hdr_end;
337
}
338
//---------------------------------------------------------------------------------
339
bool bob_dom_cut::convert(bob_dom_ibinaryfilestream& is, bob_dom_otextfilestream& os)
340
{
341
	int hdr;
342
	is >> hdr;
343
	if(hdr!=hdr_begin){
344
		error(e_badHeader);
345
		return false;
346
	}
347
 
348
	if(peek(is)==bob_dom_info::hdr_begin){
349
		if(!info.load(is)){
350
			for(ErrorIterator &it=info.errors.begin(); it!=info.errors.end(); ++it){
351
				error(it->code, "info: %s", it->text);
352
			}
353
			return false;
354
		}
355
	}
356
 
357
	is >> version;
358
 
359
	os << info << endl << "VER: " << autoSemicolons << version << endl << endl;
360
 
361
	is >> m_storedPathCount;
362
 
363
	child_type *ch;
364
	for(int i=0; i < m_storedPathCount; i++){
365
		ch=new bob_dom_path(m_settings);
366
		bool bRes=ch->load(is, version);
367
 
368
		for(ErrorIterator &it=ch->errors.begin(); it!=ch->errors.end(); ++it){
369
			error(it->code, "path[%d]->%s", i, it->text);
370
		}
371
 
372
		if(bRes)
373
			ch->toFile(os, i);
374
 
375
		delete ch;
376
		if(bRes==false) return false;
377
	}
378
 
379
	is >> hdr;
380
	if(hdr!=hdr_end)
381
		error(e_badEndHeader);
382
	return hdr==hdr_end;
383
}
384
//---------------------------------------------------------------------------------
385
bool bob_dom_cut::toFile(bob_dom_obinaryfilestream& os)
386
{
387
	os << hdr_begin << info << version << (int)size();
388
 
389
	for(iterator &it=begin(); it!=end(); ++it){
390
		it->toFile(os, version);
391
	}
392
	os << hdr_end;
393
 
394
	return os.good();
395
}
396
//---------------------------------------------------------------------------------
397
bool bob_dom_cut::toFile(bob_dom_otextfilestream& os)
398
{
399
	os << noSemicolons << info << endl;
400
	os << "VER: " << autoSemicolons << version << endl << endl;
401
 
402
	int idx=0;
403
	for(iterator &it=begin(); it!=end(); ++it){
404
		it->toFile(os, idx++);
405
		os << endl;
406
	}
407
 
408
	return os.good();
409
}
410
//---------------------------------------------------------------------------------
411
// NOTES - section NOTE
412
bool bob_dom_notes::load(bob_dom_ibinaryfilestream& is, int lineCount)
413
{
414
	int hdr;
415
 
416
	is >> hdr;
417
	if(hdr!=hdr_begin){
418
		error(e_badHeader);
419
		return false;
420
	}
421
	child_type *ch;
422
	for(int i=0; i < lineCount; i++){
423
		ch=createChild();
424
		if(ch->load(is)==false){
425
			error(ch->errorCode, "line[%d]: %s", i, bob_traslate_error(ch->errorCode));
426
			return false;
427
		}
428
	}
429
	is >> hdr;
430
	if(hdr!=hdr_end)
431
		error(e_badEndHeader);
432
 
433
	return hdr==hdr_end && !is.fail();
434
}
435
//---------------------------------------------------------------------------------
436
bool bob_dom_notes::toFile(bob_dom_obinaryfilestream& os)
437
{
438
	if(size()==0) return true;
439
 
440
	os << hdr_begin;
441
	for(iterator &it=begin(); it!=end(); ++it){
442
		it->toFile(os);
443
	}
444
	os << hdr_end;
445
	return os.good();
446
}
447
//---------------------------------------------------------------------------------
448
bool bob_dom_notes::toFile(bob_dom_otextfilestream& os)
449
{
450
 os << noSemicolons << "T // Notes" << endl;
451
	for(iterator &it=begin(); it!=end(); ++it){
452
		it->toFile(os);
453
		os << endl;
454
	}
455
	os << -1 << " // end of Notes" << endl;
456
	return os.good();
457
}
458
//---------------------------------------------------------------------------------
459
// NOTE - object
460
bool bob_note::load(bob_dom_ibinaryfilestream& is)
461
{
462
	is >> value;
463
	is >> text;
464
	if(is.fail())
465
		errorCode=e_notEnoughData;
466
	return !is.fail();
467
}
468
//---------------------------------------------------------------------------------
469
bool bob_note::toFile(bob_dom_obinaryfilestream& os)
470
{
471
	os << value << text;
472
	return os.good();
473
}
474
//---------------------------------------------------------------------------------
475
bool bob_note::toFile(bob_dom_otextfilestream& os)
476
{
477
	os << autoSemicolons << value << text;
478
	return os.good();
479
}
480
//---------------------------------------------------------------------------------
481
bool bob_dom_constants::load(bob_dom_ibinaryfilestream& is)
482
{
483
	int hdr, count;
484
	is >> hdr;
485
	if(hdr!=hdr_begin){
486
		error(e_badHeader);
487
		return false;
488
	}
489
 
490
	is >> count;
491
 
492
	constant c;
493
	for(int i=0; i < count; i++){
494
		c.load(is);
495
		values.push_back(c);
496
	}
497
	is >> hdr;
498
	if(hdr!=hdr_end){
499
		error(e_badEndHeader);
500
		return false;
501
	}
502
	return is.good();
503
}
504
//---------------------------------------------------------------------------------
505
bool bob_dom_constants::toFile(bob_dom_obinaryfilestream& os)
506
{
507
	if(values.size()==0) return true;
508
 
509
	os << hdr_begin << (int)values.size();
510
 
511
	for(iterator &it=values.begin(); it!=values.end(); ++it){
512
		(*it).toFile(os);
513
	}
514
	os << hdr_end;
515
	return os.good();
516
}
517
//---------------------------------------------------------------------------------
518
bool bob_dom_constants::toFile(bob_dom_otextfilestream& os)
519
{
520
	if(values.size()==0) return true;
521
 
522
	os << noSemicolons << "K " << autoSemicolons << (int)values.size();
523
	for(iterator &it=values.begin(); it!=values.end(); ++it){
524
		(*it).toFile(os);
525
	}
526
	os << noSemicolons;
527
	return os.good();
528
}
529
//---------------------------------------------------------------------------------
530
bool bob_dom_constants::constant::load(bob_dom_ibinaryfilestream& is)
531
{
532
	is >> a >> b;
533
	return is.good();
534
}
535
//---------------------------------------------------------------------------------
536
bool bob_dom_constants::constant::toFile(bob_dom_obinaryfilestream& os)
537
{
538
	os << a << b;
539
	return os.good();
540
}
541
//---------------------------------------------------------------------------------
542
bool bob_dom_constants::constant::toFile(bob_dom_otextfilestream& os)
543
{
544
	os << a << b;
545
	return os.good();
546
}
547
//---------------------------------------------------------------------------------