1 /****************************************************************************
2  *               messageoutput.h
3  *
4  * This module contains the basic C++ interface for message output.
5  *
6  * from Persistence of Vision(tm) Ray Tracer version 3.6.
7  * Copyright 1991-2003 Persistence of Vision Team
8  * Copyright 2003-2004 Persistence of Vision Raytracer Pty. Ltd.
9  *---------------------------------------------------------------------------
10  * NOTICE: This source code file is provided so that users may experiment
11  * with enhancements to POV-Ray and to port the software to platforms other
12  * than those supported by the POV-Ray developers. There are strict rules
13  * regarding how you are permitted to use this file. These rules are contained
14  * in the distribution and derivative versions licenses which should have been
15  * provided with this file.
16  *
17  * These licences may be found online, linked from the end-user license
18  * agreement that is located at http://www.povray.org/povlegal.html
19  *---------------------------------------------------------------------------
20  * This program is based on the popular DKB raytracer version 2.12.
21  * DKBTrace was originally written by David K. Buck.
22  * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
23  *---------------------------------------------------------------------------
24  * $File: //depot/povray/3.6-release/source/frontend/messageoutput.cpp $
25  * $Revision: #2 $
26  * $Change: 2939 $
27  * $DateTime: 2004/07/04 13:43:26 $
28  * $Author: root $
29  * $Log$
30  *****************************************************************************/
31 
32 #include <algorithm>
33 
34 #include "configfrontend.h"
35 
36 #include "messageoutput.h"
37 #include "povmsgid.h"
38 #include "pov_err.h"
39 
40 BEGIN_POV_FRONTEND_NAMESPACE
41 
42 const int Num_Echo_Lines = 5; // FIXME
43 
MessageOutput(POVMSContext context)44 MessageOutput::MessageOutput(POVMSContext context) : POVMS_MessageReceiver(context), output_string_buffer_size(1024 * 8)
45 {
46 	output_string_buffer = new char[output_string_buffer_size];
47 
48 	for(int i = 0; i < MAX_STREAMS; i++)
49 	{
50 		streams[i] = NULL;
51 		streamnames[i] = NULL;
52 		consoleoutput[i] = false;
53 	}
54 
55 	InstallFront(kPOVMsgClass_Miscellaneous, kPOVMsgIdent_InitInfo, this,  &MessageOutput::InitInfo);
56 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderOptions, this, &MessageOutput::RenderOptions);
57 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderStarted, this, &MessageOutput::RenderStarted);
58 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_FrameStatistics, this, &MessageOutput::FrameStatistics);
59 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_ParseStatistics, this, &MessageOutput::ParseStatistics);
60 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderStatistics, this, &MessageOutput::RenderStatistics);
61 	InstallBack(kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderDone, this, &MessageOutput::RenderDone);
62 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_Progress, this, &MessageOutput::Progress);
63 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_Warning, this, &MessageOutput::Warning);
64 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_Error, this, &MessageOutput::Error);
65 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_FatalError, this, &MessageOutput::FatalError);
66 	InstallFront(kPOVMsgClass_RenderOutput, kPOVMsgIdent_Debug, this, &MessageOutput::DebugInfo);
67 }
68 
~MessageOutput()69 MessageOutput::~MessageOutput()
70 {
71 	delete[] output_string_buffer;
72 }
73 
Printfile(int stream,const char * filename,unsigned long offset,int lines)74 void MessageOutput::Printfile(int stream, const char *filename, unsigned long offset, int lines)
75 {
76 	if(streams[stream] != NULL)
77 		streams[stream]->printfile(filename, offset, lines);
78 	if(streams[ALL_STREAM] != NULL)
79 		streams[ALL_STREAM]->printfile(filename, offset, lines);
80 }
81 
Printf(int stream,const char * format,...)82 void MessageOutput::Printf(int stream, const char *format, ...)
83 {
84 	va_list marker;
85 	char localvsbuffer[1024];
86 
87 	va_start(marker, format);
88 	vsnprintf(localvsbuffer, 1023, format, marker);
89 	va_end(marker);
90 
91 	if(streams[stream] != NULL)
92 		streams[stream]->print(localvsbuffer);
93 	if(streams[ALL_STREAM] != NULL)
94 		streams[ALL_STREAM]->print(localvsbuffer);
95 }
96 
Flush(int stream)97 void MessageOutput::Flush(int stream)
98 {
99 	if(streams[stream] != NULL)
100 		streams[stream]->flush();
101 	if(streams[ALL_STREAM] != NULL)
102 		streams[ALL_STREAM]->flush();
103 }
104 
InitInfo(POVMSObjectPtr msg,POVMSObjectPtr,int)105 void MessageOutput::InitInfo(POVMSObjectPtr msg, POVMSObjectPtr, int)
106 {
107 	const int NUMBER_OF_AUTHORS_ACROSS = 4;
108 	POVMSAttributeList attrlist;
109 	POVMSAttribute item;
110 	char charbuf[1024];
111 	int h, i, j;
112 	int cnt;
113 	int l;
114 
115 	Flush(STATUS_STREAM);
116 	Flush(DEBUG_STREAM);
117 
118 	l = 1024;
119 	charbuf[0] = 0;
120 	if(POVMSUtil_GetString(msg, kPOVAttrib_CoreVersion, charbuf, &l) == kNoErr)
121 		Printf(BANNER_STREAM, "%s\n", charbuf);
122 
123 	l = 1024;
124 	charbuf[0] = 0;
125 	if(POVMSUtil_GetString(msg, kPOVAttrib_EnglishText, charbuf, &l) == kNoErr)
126 		Printf(BANNER_STREAM, "%s\n", charbuf);
127 
128 	Printf(BANNER_STREAM, "\n");
129 
130 	Printf(BANNER_STREAM, "Primary POV-Ray 3.5/3.6 Developers: (Alphabetically)\n");
131 
132 	if(POVMSObject_Get(msg, &attrlist, kPOVAttrib_PrimaryDevs) == kNoErr)
133 	{
134 		cnt = 0;
135 
136 		if(POVMSAttrList_Count(&attrlist, &cnt) == kNoErr)
137 		{
138 			for(i = 0, h = 1; h <= cnt; i++)
139 			{
140 				for(j = 0; (j < NUMBER_OF_AUTHORS_ACROSS) && (h <= cnt); j++, h++)
141 				{
142 					if(POVMSAttrList_GetNth(&attrlist, h, &item) == kNoErr)
143 					{
144 						l = 1023;
145 						charbuf[0] = 0;
146 						if(POVMSAttr_Get(&item, kPOVMSType_CString, charbuf, &l) == kNoErr)
147 							Printf(BANNER_STREAM, "  %-18s", charbuf);
148 
149 						(void)POVMSAttr_Delete(&item);
150 					}
151 				}
152 				Printf(BANNER_STREAM, "\n");
153 			}
154 		}
155 
156 		(void)POVMSAttrList_Delete(&attrlist);
157 	}
158 
159     Printf(BANNER_STREAM, "\n");
160     Printf(BANNER_STREAM, "Contributing Authors: (Alphabetically)\n");
161 
162 	if(POVMSObject_Get(msg, &attrlist, kPOVAttrib_ContributingDevs) == kNoErr)
163 	{
164 		cnt = 0;
165 
166 		if(POVMSAttrList_Count(&attrlist, &cnt) == kNoErr)
167 		{
168 			for(i = 0, h = 1; h <= cnt; i++)
169 			{
170 				for(j = 0; (j < NUMBER_OF_AUTHORS_ACROSS) && (h <= cnt); j++, h++)
171 				{
172 					if(POVMSAttrList_GetNth(&attrlist, h, &item) == kNoErr)
173 					{
174 						l = 1023;
175 						charbuf[0] = 0;
176 						if(POVMSAttr_Get(&item, kPOVMSType_CString, charbuf, &l) == kNoErr)
177 							Printf(BANNER_STREAM, "  %-18s", charbuf);
178 
179 						(void)POVMSAttr_Delete(&item);
180 					}
181 				}
182 				Printf(BANNER_STREAM, "\n");
183 			}
184 		}
185 
186 		(void)POVMSAttrList_Delete(&attrlist);
187 	}
188 
189     Printf(BANNER_STREAM, "\n");
190     Printf(BANNER_STREAM, "Other contributors are listed in the documentation.\n");
191 	Printf(BANNER_STREAM, "\n");
192 
193 	if(POVMSObject_Get(msg, &attrlist, kPOVAttrib_ImageLibVersions) == kNoErr)
194 	{
195 		cnt = 0;
196 
197 		if(POVMSAttrList_Count(&attrlist, &cnt) == kNoErr)
198 		{
199 			if(cnt > 0)
200 			{
201 				Printf(BANNER_STREAM, "Support libraries used by POV-Ray:\n");
202 
203 				for(i = 1; i <= cnt; i++)
204 				{
205 					if(POVMSAttrList_GetNth(&attrlist, i, &item) == kNoErr)
206 					{
207 						l = 1023;
208 						charbuf[0] = 0;
209 						if(POVMSAttr_Get(&item, kPOVMSType_CString, charbuf, &l) == kNoErr)
210 							Printf(BANNER_STREAM, "  %s\n", charbuf);
211 
212 						(void)POVMSAttr_Delete(&item);
213 					}
214 				}
215 			}
216 		}
217 
218 		(void)POVMSAttrList_Delete(&attrlist);
219 	}
220 }
221 
RenderOptions(POVMSObjectPtr msg,POVMSObjectPtr,int)222 void MessageOutput::RenderOptions(POVMSObjectPtr msg, POVMSObjectPtr, int)
223 {
224 	POVMSAttribute attr;
225 	POVMSInt i, i2;
226 	POVMSFloat f, f2, f3, f4;
227 	POVMSBool b;
228 	char charbuf[1024];
229 	char *t;
230 	int outputQuality;
231 	int outputCompression;
232 	int l;
233 	char outputFormat;
234 
235 	Flush(STATUS_STREAM);
236 	Flush(DEBUG_STREAM);
237 
238 	Printf(RENDER_STREAM, "Parsing Options\n");
239 
240 	f = 0.0;
241 	l = 1024;
242 	charbuf[0] = 0;
243 	(void)POVMSUtil_GetString(msg, kPOVAttrib_InputFile, charbuf, &l);
244 	(void)POVMSUtil_GetFloat(msg, kPOVAttrib_Version, &f);
245 	Printf(RENDER_STREAM, "  Input file: %s (compatible to version %1.2f)\n", charbuf, (double)f);
246 	Printf(RENDER_STREAM, "  Remove bounds.......%s\n  Split unions........%s\n",
247 	              GetOptionSwitchString(msg, kPOVAttrib_RemoveBounds), GetOptionSwitchString(msg, kPOVAttrib_SplitUnions));
248 
249 	Printf(RENDER_STREAM, "  Library paths:\n");
250 	if(POVMSObject_Get(msg, &attr, kPOVAttrib_LibraryPath) == kNoErr)
251 	{
252 		int cnt = 0;
253 
254 		if(POVMSAttrList_Count(&attr, &cnt) == kNoErr)
255 		{
256 			POVMSAttribute item;
257 			long ii;
258 
259 			for(ii = 1; ii <= cnt; ii++)
260 			{
261 				if(POVMSAttrList_GetNth(&attr, ii, &item) == kNoErr)
262 				{
263 					l = 1023;
264 					charbuf[0] = 0;
265 					(void)POVMSAttr_Get(&item, kPOVMSType_CString, charbuf, &l);
266 					Printf(RENDER_STREAM, "    %s\n", charbuf);
267 
268 					(void)POVMSAttr_Delete(&item);
269 				}
270 			}
271 		}
272 
273 		(void)POVMSAttr_Delete(&attr);
274 	}
275 
276 	Printf(RENDER_STREAM, "Output Options\n");
277 
278 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_Width, &i);
279 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_Height, &i2);
280 	(void)POVMSUtil_GetFloat(msg, kPOVAttrib_StartRow, &f);
281 	(void)POVMSUtil_GetFloat(msg, kPOVAttrib_EndRow, &f2);
282 	(void)POVMSUtil_GetFloat(msg, kPOVAttrib_StartColumn, &f3);
283 	(void)POVMSUtil_GetFloat(msg, kPOVAttrib_EndColumn, &f4);
284 	Printf(RENDER_STREAM, "  Image resolution %d by %d (rows %d to %d, columns %d to %d).\n",
285 	              (int)i, (int)i2, (int)(f + 1), (int)f2, (int)(f3 + 1), (int)f4);
286 
287 	if(POVMSUtil_GetInt(msg, kPOVAttrib_OutputFileType, &i) == kNoErr)
288 		outputFormat = (char)tolower(i);
289 	if(POVMSUtil_GetInt(msg, kPOVAttrib_BitsPerColor, &i) == kNoErr)
290 		outputQuality = i;
291 	if(POVMSUtil_GetInt(msg, kPOVAttrib_Compression, &i) == kNoErr)
292 	{
293 		if(toupper(outputFormat) == 'J')
294 		{
295 			outputQuality = i;
296 			outputQuality = max(0, outputQuality);
297 			outputQuality = min(100, outputQuality);
298 		}
299 	}
300 
301 	b = false;
302 	(void)POVMSUtil_GetBool(msg, kPOVAttrib_OutputToFile, &b);
303 	if(b == true)
304 	{
305 		char charbuf2[1024];
306 		char *al = "";
307 
308 		l = 1023;
309 		charbuf2[0] = 0;
310 		(void)POVMSUtil_GetString(msg, kPOVAttrib_OutputPath, charbuf2, &l);
311 		l = 1023;
312 		charbuf[0] = 0;
313 		(void)POVMSUtil_GetString(msg, kPOVAttrib_OutputFile, charbuf, &l);
314 		b = false;
315 		(void)POVMSUtil_GetBool(msg, kPOVAttrib_OutputAlpha, &b);
316 
317 		if(toupper(outputFormat) == 'J')
318 		{
319 			outputCompression = outputQuality;
320 			outputQuality = 8;
321 		}
322 
323 		if(b == true)
324 		{
325 			outputQuality *= 4;
326 			al = " with alpha";
327 		}
328 		else
329 			outputQuality *= 3;
330 
331 		switch(toupper(outputFormat))
332 		{
333 			case 'C': t = "RLE Targa";       break;
334 			case 'N': t = "PNG";             break;
335 			case 'J': t = "JPEG";            break;
336 			case 'P': t = "PPM";             break;
337 			case 'S': t = "(system format)"; break;
338 			case 'T': t = "Targa";           break;
339 			default:  t = "(none)";          break;
340 		}
341 
342 		if(toupper(outputFormat) == 'J')
343 			Printf(RENDER_STREAM, "  Output file: %s%s, %d bpp, quality %d%s%s %s\n", charbuf2, charbuf, outputQuality, outputCompression, "%", al, t);
344 		else
345 			Printf(RENDER_STREAM, "  Output file: %s%s, %d bpp%s %s\n", charbuf2, charbuf, outputQuality, al, t);
346 	}
347 
348 	b = false;
349 	(void)POVMSUtil_GetBool(msg, kPOVAttrib_Display, &b);
350 	if(b == true)
351 	{
352 		f = 0.0;
353 		(void)POVMSUtil_GetFloat(msg, kPOVAttrib_DisplayGamma, &f);
354 		Printf(RENDER_STREAM, "  Graphic display......On  (gamma: %g)\n", (float)f);
355 	}
356 	else
357 		Printf(RENDER_STREAM, "  Graphic display......Off\n");
358 
359 	i = 0;
360 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_PreviewStartSize, &i);
361 	if(i > 1)
362 	{
363 		i2 = 0;
364 		(void)POVMSUtil_GetInt(msg, kPOVAttrib_PreviewEndSize, &i2);
365 		Printf(RENDER_STREAM, "  Mosaic preview.......On  (pixel sizes %d to %d)\n", (int)i, (int)i2);
366 	}
367 	else
368 		Printf(RENDER_STREAM, "  Mosaic preview.......Off\n");
369 
370 	b = false;
371 	(void)POVMSUtil_GetBool(msg, kPOVAttrib_CreateHistogram, &b);
372 	if(b == true)
373 	{
374 		if(POVMSUtil_GetInt(msg, kPOVAttrib_HistogramFileType, &i) == kNoErr)
375 		{
376 			switch(i)
377 			{
378 		         case 'C':
379 		         case 'c':
380 					t = "CSV";
381 					break;
382 		         case 'T':
383 		         case 't':
384 					t = "TGA";
385 					break;
386 		         case 'N':
387 		         case 'n':
388 					t = "PNG";
389 					break;
390 		         case 'P' :
391 		         case 'p' :
392 					t = "PPM";
393 					break;
394 		         case 'S':
395 		         case 's':
396 					t = "(system format)";
397 					break;
398 				default:
399 					t = "(none)";
400 					break;
401 			}
402 
403 			i = 0;
404 			i2 = 0;
405 			l = 1023;
406 			charbuf[0] = 0;
407 			(void)POVMSUtil_GetInt(msg, kPOVAttrib_HistogramGridSizeX, &i);
408 			(void)POVMSUtil_GetInt(msg, kPOVAttrib_HistogramGridSizeY, &i2);
409 			(void)POVMSUtil_GetString(msg, kPOVAttrib_HistogramFile, charbuf, &l);
410 			Printf(RENDER_STREAM, "  CPU usage histogram..On  (name: %s type: %s, grid: %dx%d)\n",
411 			              charbuf, t, (int)i, (int)i2);
412 		}
413 	}
414 	else
415 		Printf(RENDER_STREAM, "  CPU usage histogram..Off\n");
416 
417 	Printf(RENDER_STREAM, "  Continued trace.....%s\n", GetOptionSwitchString(msg, kPOVAttrib_ContinueTrace));
418 
419 	Printf(RENDER_STREAM, "Tracing Options\n");
420 
421 	i = 0;
422 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_Quality, &i);
423 	Printf(RENDER_STREAM, "  Quality: %2d\n", (int)i);
424 
425 	b = false;
426 	(void)POVMSUtil_GetBool(msg, kPOVAttrib_Bounding, &b);
427 	if(b == true)
428 	{
429 		i = 0;
430 		(void)POVMSUtil_GetInt(msg, kPOVAttrib_BoundingThreshold, &i);
431 		Printf(RENDER_STREAM, "  Bounding boxes.......On   Bounding threshold: %d\n", (int)i);
432 	}
433 	else
434 		Printf(RENDER_STREAM, "  Bounding boxes.......Off\n");
435 
436 	Printf(RENDER_STREAM, "  Light Buffer........%s\n", GetOptionSwitchString(msg, kPOVAttrib_LightBuffer));
437 	Printf(RENDER_STREAM, "  Vista Buffer........%-3s", GetOptionSwitchString(msg, kPOVAttrib_VistaBuffer));
438 	b = false;
439 	(void)POVMSUtil_GetBool(msg, kPOVAttrib_VistaBuffer, &b);
440 	if(b == true)
441 		Printf(RENDER_STREAM, "  Draw Vista Buffer...%s", GetOptionSwitchString(msg, kPOVAttrib_DrawVistas));
442 	Printf(RENDER_STREAM, "\n");
443 
444 	b = false;
445 	(void)POVMSUtil_GetBool(msg, kPOVAttrib_Antialias, &b);
446 	if(b == true)
447 	{
448 		i = 0;
449 		i2 = 0;
450 		f = 0.0;
451 		f2 = 0.0;
452 		(void)POVMSUtil_GetInt(msg, kPOVAttrib_SamplingMethod, &i);
453 		(void)POVMSUtil_GetInt(msg, kPOVAttrib_AntialiasDepth, &i2);
454 		(void)POVMSUtil_GetFloat(msg, kPOVAttrib_AntialiasThreshold, &f);
455 		(void)POVMSUtil_GetFloat(msg, kPOVAttrib_JitterAmount, &f2);
456 		Printf(RENDER_STREAM, "  Antialiasing.........On  (Method %d, Threshold %.3f, Depth %d, Jitter %.2f)\n",
457 		              (int)i, (float)f, (int)i2, (float)f2);
458 	}
459 	else
460 		Printf(RENDER_STREAM, "  Antialiasing.........Off\n");
461 
462 	i = 1;
463 	i2 = 1;
464 	f = 0.0;
465 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_InitialFrame, &i);
466 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_FinalFrame, &i2);
467 	(void)POVMSUtil_GetFloat(msg, kPOVAttrib_Clock, &f);
468 	if((i != 1) || (i2 != 1) || (i != i2) || (f != 0.0))
469 	{
470 		Printf(RENDER_STREAM, "Animation Options\n");
471 		Printf(RENDER_STREAM, "  Initial Frame: %8d  Final Frame: %8d\n", (int)i, (int)i2);
472 		f = 0.0;
473 		f2 = 0.0;
474 		(void)POVMSUtil_GetFloat(msg, kPOVAttrib_InitialClock, &f);
475 		(void)POVMSUtil_GetFloat(msg, kPOVAttrib_FinalClock, &f2);
476 		Printf(RENDER_STREAM, "  Initial Clock: %8.3f  Final Clock: %8.3f\n", (float)f, (float)f2);
477 		Printf(RENDER_STREAM, "  Cyclic Animation....%s  Field render........%s  Odd lines/frames....%s",
478 		              GetOptionSwitchString(msg, kPOVAttrib_CyclicAnimation),
479 		              GetOptionSwitchString(msg, kPOVAttrib_FieldRender),
480 		              GetOptionSwitchString(msg, kPOVAttrib_OddField));
481 	}
482 	else
483 		Printf(RENDER_STREAM, "  Clock value: %8.3f  (Animation off)", (float)f);
484 	Printf(RENDER_STREAM, "\n");
485 }
486 
RenderStarted(POVMSObjectPtr msg,POVMSObjectPtr,int)487 void MessageOutput::RenderStarted(POVMSObjectPtr msg, POVMSObjectPtr, int)
488 {
489 	POVMSType streamTypeUtilData[MAX_STREAMS] =
490 	{
491 		kPOVMSType_WildCard,
492 		kPOVMSType_WildCard,
493 		kPOVAttrib_DebugFile,
494 		kPOVAttrib_FatalFile,
495 		kPOVAttrib_RenderFile,
496 		kPOVAttrib_StatisticsFile,
497 		kPOVAttrib_WarningFile,
498 		kPOVAttrib_AllFile
499 	};
500 	POVMSBool b;
501 
502 	b = true;
503 	if(POVMSObject_Exist(msg, kPOVAttrib_AllConsole) == kNoErr)
504 		(void)POVMSUtil_GetBool(msg, kPOVAttrib_AllConsole, &b);
505 	consoleoutput[BANNER_STREAM] =
506 	consoleoutput[STATUS_STREAM] =
507 	consoleoutput[DEBUG_STREAM] =
508 	consoleoutput[FATAL_STREAM] =
509 	consoleoutput[RENDER_STREAM] =
510 	consoleoutput[STATISTIC_STREAM] =
511 	consoleoutput[WARNING_STREAM] =
512 	consoleoutput[ALL_STREAM] = b;
513 
514 	b = true;
515 	if(POVMSObject_Exist(msg, kPOVAttrib_DebugConsole) == kNoErr)
516 		(void)POVMSUtil_GetBool(msg, kPOVAttrib_DebugConsole, &b);
517 	consoleoutput[DEBUG_STREAM] = b;
518 
519 	b = true;
520 	if(POVMSObject_Exist(msg, kPOVAttrib_FatalConsole) == kNoErr)
521 		(void)POVMSUtil_GetBool(msg, kPOVAttrib_FatalConsole, &b);
522 	consoleoutput[FATAL_STREAM] = b;
523 
524 	b = true;
525 	if(POVMSObject_Exist(msg, kPOVAttrib_RenderConsole) == kNoErr)
526 		(void)POVMSUtil_GetBool(msg, kPOVAttrib_RenderConsole, &b);
527 	consoleoutput[RENDER_STREAM] = b;
528 
529 	b = true;
530 	if(POVMSObject_Exist(msg, kPOVAttrib_StatisticsConsole) == kNoErr)
531 		(void)POVMSUtil_GetBool(msg, kPOVAttrib_StatisticsConsole, &b);
532 	consoleoutput[STATISTIC_STREAM] = b;
533 
534 	b = true;
535 	if(POVMSObject_Exist(msg, kPOVAttrib_WarningConsole) == kNoErr)
536 		(void)POVMSUtil_GetBool(msg, kPOVAttrib_WarningConsole, &b);
537 	consoleoutput[WARNING_STREAM] = b;
538 
539 	for(int i = 0; i < MAX_STREAMS; i++)
540 	{
541 		if(POVMSObject_Exist(msg, streamTypeUtilData[i]) == kNoErr)
542 		{
543 			int l = 0;
544 			if(POVMSUtil_GetStringLength(msg, streamTypeUtilData[i], &l) == kNoErr)
545 			{
546 				streamnames[i] = new char[l];
547 				streamnames[i][0] = 0;
548 				(void)POVMSUtil_GetString(msg, streamTypeUtilData[i], streamnames[i], &l);
549 			}
550 			else
551 				streamnames[i] = NULL;
552 		}
553 		else
554 			streamnames[i] = NULL;
555 	}
556 
557 	b = false;
558 	if(POVMSUtil_GetBool(msg, kPOVAttrib_ContinueTrace, &b) != kNoErr)
559 		b = false;
560 	OpenStreams(b);
561 
562 	Flush(STATUS_STREAM);
563 	Flush(DEBUG_STREAM);
564 
565 	Printf(RENDER_STREAM, "Redirecting Options\n");
566 
567 	Printf(RENDER_STREAM, "  All Streams to console.........%s", GetOptionSwitchString(msg, kPOVAttrib_AllConsole, true));
568 	if(streamnames[ALL_STREAM] != NULL)
569 		Printf(RENDER_STREAM, "  and file %s\n", streamnames[ALL_STREAM]);
570 	else
571 		Printf(RENDER_STREAM, "\n");
572 
573 	Printf(RENDER_STREAM, "  Debug Stream to console........%s", GetOptionSwitchString(msg, kPOVAttrib_DebugConsole, true));
574 	if(streamnames[DEBUG_STREAM] != NULL)
575 		Printf(RENDER_STREAM, "  and file %s\n", streamnames[DEBUG_STREAM]);
576 	else
577 		Printf(RENDER_STREAM, "\n");
578 
579 	Printf(RENDER_STREAM, "  Fatal Stream to console........%s", GetOptionSwitchString(msg, kPOVAttrib_FatalConsole, true));
580 	if(streamnames[FATAL_STREAM] != NULL)
581 		Printf(RENDER_STREAM, "  and file %s\n", streamnames[FATAL_STREAM]);
582 	else
583 		Printf(RENDER_STREAM, "\n");
584 
585 	Printf(RENDER_STREAM, "  Render Stream to console.......%s", GetOptionSwitchString(msg, kPOVAttrib_RenderConsole, true));
586 	if(streamnames[RENDER_STREAM] != NULL)
587 		Printf(RENDER_STREAM, "  and file %s\n", streamnames[RENDER_STREAM]);
588 	else
589 		Printf(RENDER_STREAM, "\n");
590 
591 	Printf(RENDER_STREAM, "  Statistics Stream to console...%s", GetOptionSwitchString(msg, kPOVAttrib_StatisticsConsole, true));
592 	if(streamnames[STATISTIC_STREAM] != NULL)
593 		Printf(RENDER_STREAM, "  and file %s\n", streamnames[STATISTIC_STREAM]);
594 	else
595 		Printf(RENDER_STREAM, "\n");
596 
597 	Printf(RENDER_STREAM, "  Warning Stream to console......%s", GetOptionSwitchString(msg, kPOVAttrib_WarningConsole, true));
598 	if(streamnames[WARNING_STREAM] != NULL)
599 		Printf(RENDER_STREAM, "  and file %s\n", streamnames[WARNING_STREAM]);
600 	else
601 		Printf(RENDER_STREAM, "\n");
602 }
603 
FrameStatistics(POVMSObjectPtr msg,POVMSObjectPtr,int)604 void MessageOutput::FrameStatistics(POVMSObjectPtr msg, POVMSObjectPtr, int)
605 {
606 	POVMSObject object;
607 	int ret = 0;
608 	int i = 0;
609 
610 	Flush(STATUS_STREAM);
611 	Flush(DEBUG_STREAM);
612 
613 	ret = POVMSObject_Get(msg, &object, kPOVAttrib_FrameTime);
614 	if(ret == kNoErr)
615 		Printf(STATISTIC_STREAM, "Frame Processing Times\n");
616 
617 	if(ret == kNoErr)
618 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_ParseTime, &i);
619 	if(ret == kNoErr)
620 		Printf(STATISTIC_STREAM, "  Parse Time:  %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
621 
622 	if(ret == kNoErr)
623 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_PhotonTime, &i);
624 	if(ret == kNoErr)
625 		Printf(STATISTIC_STREAM, "  Photon Time: %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
626 
627 	if(ret == kNoErr)
628 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_TraceTime, &i);
629 	if(ret == kNoErr)
630 		Printf(STATISTIC_STREAM, "  Render Time: %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
631 
632 	if(ret == kNoErr)
633 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_TotalTime, &i);
634 	if(ret == kNoErr)
635 		Printf(STATISTIC_STREAM, "  Total Time:  %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
636 
637 	(void)POVMSObject_Delete(&object);
638 
639 	if(ret != kNoErr)
640 		throw ret;
641 }
642 
ParseStatistics(POVMSObjectPtr msg,POVMSObjectPtr,int)643 void MessageOutput::ParseStatistics(POVMSObjectPtr msg, POVMSObjectPtr, int)
644 {
645 	POVMSLong ll = 0;
646 	int ret = kNoErr;
647 	int l = 0;
648 	int s = 0;
649 	int i = 0;
650 
651 	Flush(STATUS_STREAM);
652 	Flush(DEBUG_STREAM);
653 
654 	ret = POVMSUtil_GetInt(msg, kPOVAttrib_FiniteObjects, &s);
655 	if(ret == kNoErr)
656 		ret = POVMSUtil_GetInt(msg, kPOVAttrib_InfiniteObjects, &i);
657 	if(ret == kNoErr)
658 		ret = POVMSUtil_GetInt(msg, kPOVAttrib_LightSources, &l);
659 	if(ret == kNoErr)
660 	{
661 		Printf(STATISTIC_STREAM, "Scene Statistics\n");
662 		Printf(STATISTIC_STREAM, "  Finite objects:   %10d\n", s);
663 		Printf(STATISTIC_STREAM, "  Infinite objects: %10d\n", i);
664 		Printf(STATISTIC_STREAM, "  Light sources:    %10d\n", l);
665 		Printf(STATISTIC_STREAM, "  Total:            %10d\n", s + i + l);
666 	}
667 
668 	if(ret != kNoErr)
669 		throw ret;
670 }
671 
RenderStatistics(POVMSObjectPtr msg,POVMSObjectPtr,int)672 void MessageOutput::RenderStatistics(POVMSObjectPtr msg, POVMSObjectPtr, int)
673 {
674 	POVMSAttribute attr;
675 	POVMSLong l, l2;
676 	POVMSFloat f, f2;
677 	long Pixels_In_Image;
678 	int i, i2;
679 
680 	Flush(STATUS_STREAM);
681 	Flush(DEBUG_STREAM);
682 
683 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_Width, &i);
684 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_Height, &i2);
685 	Pixels_In_Image = (long)i * (long)i2;
686 
687 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_Pixels, &l);
688 	if(Pixels_In_Image > POVMSLongToCDouble(l))
689 		Printf(STATISTIC_STREAM, "Render Statistics (Partial Image Rendered)\n");
690 	else
691 		Printf(STATISTIC_STREAM, "Render Statistics\n");
692 
693 	Printf(STATISTIC_STREAM, "Image Resolution %d x %d\n", i, i2);
694 
695 	Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
696 
697 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_Pixels, &l);
698 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_PixelSamples, &l2);
699 	if(POVMSLongToCDouble(l) > 0.5)
700 		Printf(STATISTIC_STREAM, "Pixels:  %15.0f   Samples: %15.0f   Smpls/Pxl: %.2f\n",
701 		              POVMSLongToCDouble(l), POVMSLongToCDouble(l2), POVMSLongToCDouble(l2) / POVMSLongToCDouble(l));
702 	else
703 		Printf(STATISTIC_STREAM, "Pixels:  %15.0f   Samples: %15.0f   Smpls/Pxl: -\n",
704 		              POVMSLongToCDouble(l), POVMSLongToCDouble(l2));
705 
706 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_Rays, &l);
707 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_RaysSaved, &l2);
708 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_TraceLevel, &i);
709 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_MaxTraceLevel, &i2);
710 	Printf(STATISTIC_STREAM, "Rays:    %15.0f   Saved:   %15.0f   Max Level: %d/%d\n",
711 	              POVMSLongToCDouble(l), POVMSLongToCDouble(l2), i, i2);
712 
713 	Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
714 	Printf(STATISTIC_STREAM, "Ray->Shape Intersection          Tests       Succeeded  Percentage\n");
715 	Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
716 
717 	if(POVMSObject_Get(msg, &attr, kPOVAttrib_ObjectIStats) == kNoErr)
718 	{
719 		int cnt = 0;
720 
721 		if(POVMSAttrList_Count(&attr, &cnt) == kNoErr)
722 		{
723 			POVMSObject obj;
724 			int ii, len;
725 			char str[40];
726 
727 			for(ii = 1; ii <= cnt; ii++)
728 			{
729 				if(POVMSAttrList_GetNth(&attr, ii, &obj) == kNoErr)
730 				{
731 					len = 40;
732 					str[0] = 0;
733 					(void)POVMSUtil_GetString(&obj, kPOVAttrib_ObjectName, str, &len);
734 					(void)POVMSUtil_GetLong(&obj, kPOVAttrib_ISectsTests, &l);
735 					(void)POVMSUtil_GetLong(&obj, kPOVAttrib_ISectsSucceeded, &l2);
736 
737 					if(POVMSLongToCDouble(l) > 0.5)
738 					{
739 						Printf(STATISTIC_STREAM, "%-22s  %14.0f  %14.0f  %8.2f\n", str,
740 						              POVMSLongToCDouble(l), POVMSLongToCDouble(l2),
741 						              100.0 * POVMSLongToCDouble(l2) / POVMSLongToCDouble(l));
742 					}
743 
744 					(void)POVMSAttr_Delete(&obj);
745 				}
746 			}
747 		}
748 
749 		(void)POVMSAttr_Delete(&attr);
750 	}
751 
752 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_IsoFindRoot, &l);
753 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_FunctionVMCalls, &l2);
754 	if((POVMSLongToCDouble(l) > 0.5) || (POVMSLongToCDouble(l2) > 0.5))
755 	{
756 		Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
757     	if(POVMSLongToCDouble(l) > 0.5)
758     		Printf(STATISTIC_STREAM, "Isosurface roots:   %15.0f\n", POVMSLongToCDouble(l));
759     	if(POVMSLongToCDouble(l2) > 0.5)
760     		Printf(STATISTIC_STREAM, "Function VM calls:  %15.0f\n", POVMSLongToCDouble(l2));
761 	}
762 
763 	Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
764 
765 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_PolynomTest, &l);
766 	if(POVMSLongToCDouble(l) > 0.5)
767 	{
768 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_RootsEliminated, &l2);
769 		Printf(STATISTIC_STREAM, "Roots tested:       %15.0f   eliminated:      %15.0f\n",
770 		              POVMSLongToCDouble(l), POVMSLongToCDouble(l2));
771 	}
772 
773 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_CallsToNoise, &l);
774 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_CallsToDNoise, &l2);
775 	Printf(STATISTIC_STREAM, "Calls to Noise:     %15.0f   Calls to DNoise: %15.0f\n",
776 	              POVMSLongToCDouble(l), POVMSLongToCDouble(l2));
777 
778 	Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
779 
780 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_MediaIntervals, &l);
781 	if(POVMSLongToCDouble(l) > 0.5)
782 	{
783 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_MediaSamples, &l2);
784 		Printf(STATISTIC_STREAM, "Media Intervals:    %15.0f   Media Samples:   %15.0f (%4.2f)\n",
785 		              POVMSLongToCDouble(l), POVMSLongToCDouble(l2), POVMSLongToCDouble(l2) / POVMSLongToCDouble(l));
786 	}
787 
788 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_ShadowTest, &l);
789 	if(POVMSLongToCDouble(l) > 0.5)
790 	{
791 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_ShadowTestSuc, &l2);
792 
793 		Printf(STATISTIC_STREAM, "Shadow Ray Tests:   %15.0f   Succeeded:       %15.0f\n",
794 		              POVMSLongToCDouble(l), POVMSLongToCDouble(l2));
795 	}
796 
797 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_ReflectedRays, &l);
798 	if(POVMSLongToCDouble(l) > 0.5)
799 	{
800 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_InnerReflectedRays, &l2);
801 		if(POVMSLongToCDouble(l2) > 0)
802 			Printf(STATISTIC_STREAM, "Reflected Rays:     %15.0f   Total Internal:  %15.0f\n",
803 			              POVMSLongToCDouble(l), POVMSLongToCDouble(l2));
804 	    else
805 	    	Printf(STATISTIC_STREAM, "Reflected Rays:     %15.0f\n", POVMSLongToCDouble(l));
806 	}
807 
808 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_RefractedRays, &l);
809 	if(POVMSLongToCDouble(l) > 0.5)
810 		Printf(STATISTIC_STREAM, "Refracted Rays:     %15.0f\n", POVMSLongToCDouble(l));
811 
812 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_TransmittedRays, &l);
813 	if(POVMSLongToCDouble(l) > 0.5)
814 		Printf(STATISTIC_STREAM, "Transmitted Rays:   %15.0f\n", POVMSLongToCDouble(l));
815 
816 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_IStackOverflow, &l);
817 	if(POVMSLongToCDouble(l) > 0.5)
818 		Printf(STATISTIC_STREAM, "I-Stack overflows:  %15.0f\n", POVMSLongToCDouble(l));
819 
820 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_RadGatherCount, &i);
821 	(void)POVMSUtil_GetInt(msg, kPOVAttrib_RadReuseCount, &i2);
822 	if((i > 0) || (i > 0))
823 	{
824 		Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
825 		Printf(STATISTIC_STREAM, "Radiosity samples calculated:  %15d (%.2f %%)\n", i, 100.0 * double(i) / double(i + i2));
826 		Printf(STATISTIC_STREAM, "Radiosity samples reused:      %15d\n", i2);
827 	}
828 
829 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_PhotonsShot, &l);
830 	if(POVMSLongToCDouble(l) > 0.5)
831 	{
832 		Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
833 		Printf(STATISTIC_STREAM, "Number of photons shot: %15.0f\n", POVMSLongToCDouble(l));
834 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_PhotonsStored, &l);
835 		if(POVMSLongToCDouble(l) > 0.5)
836 			Printf(STATISTIC_STREAM, "Surface photons stored: %15.0f\n", POVMSLongToCDouble(l));
837 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_MediaPhotonsStored, &l);
838 		if(POVMSLongToCDouble(l) > 0.5)
839 			Printf(STATISTIC_STREAM, "Media photons stored:   %15.0f\n", POVMSLongToCDouble(l));
840 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_GlobalPhotonsStored, &l);
841 		if(POVMSLongToCDouble(l) > 0.5)
842 			Printf(STATISTIC_STREAM, "Global photons stored:  %15.0f\n", POVMSLongToCDouble(l));
843 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_PhotonsPriQInsert, &l);
844 		if(POVMSLongToCDouble(l) > 0.5)
845 			Printf(STATISTIC_STREAM, "Priority queue insert:  %15.0f\n", POVMSLongToCDouble(l));
846 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_PhotonsPriQRemove, &l);
847 		if(POVMSLongToCDouble(l) > 0.5)
848 			Printf(STATISTIC_STREAM, "Priority queue remove:  %15.0f\n", POVMSLongToCDouble(l));
849 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_GatherPerformedCnt, &l);
850 		if(POVMSLongToCDouble(l) > 0.5)
851 			Printf(STATISTIC_STREAM, "Gather function called: %15.0f\n", POVMSLongToCDouble(l));
852 		(void)POVMSUtil_GetLong(msg, kPOVAttrib_GatherExpandedCnt, &l);
853 		if(POVMSLongToCDouble(l) > 0.5)
854 			Printf(STATISTIC_STREAM, "Gather radius expanded: %15.0f\n", POVMSLongToCDouble(l));
855 	}
856 
857 	Printf(STATISTIC_STREAM, "----------------------------------------------------------------------------\n");
858 
859 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_MinAlloc, &l);
860 	Printf(STATISTIC_STREAM, "Smallest Alloc:     %15.0f bytes\n", POVMSLongToCDouble(l));
861 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_MaxAlloc, &l);
862 	Printf(STATISTIC_STREAM, "Largest  Alloc:     %15.0f bytes\n", POVMSLongToCDouble(l));
863 
864 	l = 0;
865 	l2 = 0;
866 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_CallsToAlloc, &l);
867 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_CallsToFree, &l2);
868 	if(POVMSLongToCDouble(l) > 0.5)
869 		Printf(STATISTIC_STREAM, "Total Alloc calls:  %15.0f         Free calls:%15.0f\n", POVMSLongToCDouble(l), POVMSLongToCDouble(l2));
870 
871 	l = 0;
872 	(void)POVMSUtil_GetLong(msg, kPOVAttrib_PeakMemoryUsage, &l);
873 	if(POVMSLongToCDouble(l) > 0.5)
874 		Printf(STATISTIC_STREAM, "Peak memory used:   %15.0f bytes\n", POVMSLongToCDouble(l));
875 }
876 
RenderDone(POVMSObjectPtr msg,POVMSObjectPtr,int)877 void MessageOutput::RenderDone(POVMSObjectPtr msg, POVMSObjectPtr, int)
878 {
879 	POVMSObject object;
880 	int ret = 0;
881 	int i = 0;
882 
883 	Flush(STATUS_STREAM);
884 	Flush(DEBUG_STREAM);
885 
886 	ret = POVMSObject_Get(msg, &object, kPOVAttrib_AnimationTime);
887 	if(ret == kNoErr)
888 		Printf(STATISTIC_STREAM, "Total Scene Processing Times\n");
889 
890 	if(ret == kNoErr)
891 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_ParseTime, &i);
892 	if(ret == kNoErr)
893 		Printf(STATISTIC_STREAM, "  Parse Time:  %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
894 
895 	if(ret == kNoErr)
896 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_PhotonTime, &i);
897 	if(ret == kNoErr)
898 		Printf(STATISTIC_STREAM, "  Photon Time: %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
899 
900 	if(ret == kNoErr)
901 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_TraceTime, &i);
902 	if(ret == kNoErr)
903 		Printf(STATISTIC_STREAM, "  Render Time: %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
904 
905 	if(ret == kNoErr)
906 		ret = POVMSUtil_GetInt(&object, kPOVAttrib_TotalTime, &i);
907 	if(ret == kNoErr)
908 		Printf(STATISTIC_STREAM, "  Total Time:  %3d hours %2d minutes %2d seconds (%d seconds)\n", (int)(i / 3600), (int)((i / 60) % 60), (int)(i % 60), (int)i);
909 
910 	(void)POVMSObject_Delete(&object);
911 
912 	CloseStreams();
913 
914 	if(ret != kNoErr)
915 		throw ret;
916 }
917 
Progress(POVMSObjectPtr msg,POVMSObjectPtr,int)918 void MessageOutput::Progress(POVMSObjectPtr msg, POVMSObjectPtr, int)
919 {
920 	POVMSLong ll = 0;
921 	POVMSBool b = false;
922 	int ret = kNoErr;
923 	int l = 0;
924 	int s = 0;
925 
926 	Flush(DEBUG_STREAM);
927 
928 	ret = POVMSUtil_GetBool(msg, kPOVAttrib_ProgressStatus, &b);
929 	if(ret == kNoErr)
930 		ret = POVMSUtil_GetInt(msg, kPOVAttrib_TotalTime, &s);
931 	if(ret == kNoErr)
932 	{
933 		l = 80;
934 
935 		if(b == false)
936 		{
937 			ret = POVMSUtil_GetString(msg, kPOVAttrib_EnglishText, status_string_buffer, &l);
938 			if(ret == kNoErr)
939 				Printf(STATUS_STREAM, "\n%3d:%02d:%02d %s", (int)(s / 3600), (int)((s / 60) % 60), (int)(s % 60), status_string_buffer);
940 		}
941 		else // if(opts.Options & VERBOSE) // Should this be part of verbose reporting only or not? I really don't know which way would be better... [trf]
942 		{
943 			(void)POVMSUtil_GetString(msg, kPOVAttrib_EnglishText, status_string_buffer, &l);
944 			Printf(STATUS_STREAM, "\r%3d:%02d:%02d %s", (int)(s / 3600), (int)((s / 60) % 60), (int)(s % 60), status_string_buffer);
945 		}
946 
947 // FIXME		if(opts.Options & VERBOSE)
948 		{
949 			// animation frame progress
950 			if(POVMSUtil_GetInt(msg, kPOVAttrib_FrameCount, &l) == kNoErr)
951 			{
952 				if(POVMSUtil_GetInt(msg, kPOVAttrib_AbsoluteCurFrame, &s) == kNoErr)
953 					Printf(STATUS_STREAM, " %d of %d", s, l);
954 			}
955 			// parsing progress
956 			else if((POVMSUtil_GetLong(msg, kPOVAttrib_CurrentToken, &ll) == kNoErr) && (ll > 0))
957 			{
958 				Printf(STATUS_STREAM, " %ldK tokens", long(((POV_LONG)(ll))/1000));
959 			}
960 			// rendering progress
961 			else if(POVMSUtil_GetInt(msg, kPOVAttrib_CurrentLine, &l) == kNoErr)
962 			{
963 				if(POVMSUtil_GetInt(msg, kPOVAttrib_LineCount, &s) == kNoErr)
964 					Printf(STATUS_STREAM, " line %d of %d", l, s);
965 				if(POVMSUtil_GetInt(msg, kPOVAttrib_MosaicPreviewSize, &l) == kNoErr)
966 					Printf(STATUS_STREAM, " at %dx%d", l, l);
967 				if(POVMSUtil_GetInt(msg, kPOVAttrib_SuperSampleCount, &l) == kNoErr)
968 					Printf(STATUS_STREAM, ", %d supersamples", l);
969 				if(POVMSUtil_GetInt(msg, kPOVAttrib_RadGatherCount, &l) == kNoErr)
970 					Printf(STATUS_STREAM, ", %d rad. samples", l);
971 			}
972 			// photon progress
973 			else if(POVMSUtil_GetInt(msg, kPOVAttrib_TotalPhotonCount, &l) == kNoErr)
974 			{
975 				// sorting
976 				if(POVMSUtil_GetInt(msg, kPOVAttrib_CurrentPhotonCount, &s) == kNoErr)
977 					Printf(STATUS_STREAM, " %d of %d", s, l);
978 				// shooting
979 				else
980 				{
981 					Printf(STATUS_STREAM, " Photons %d", l);
982 					l = 0;
983 					(void)POVMSUtil_GetInt(msg, kPOVAttrib_PhotonXSamples, &l);
984 					s = 0;
985 					(void)POVMSUtil_GetInt(msg, kPOVAttrib_PhotonYSamples, &s);
986 					Printf(STATUS_STREAM, " (sampling %dx%d)", l, s);
987 				}
988 			}
989 		}
990 	}
991 
992 	if(ret != kNoErr)
993 		throw ret;
994 }
995 
Warning(POVMSObjectPtr msg,POVMSObjectPtr,int)996 void MessageOutput::Warning(POVMSObjectPtr msg, POVMSObjectPtr, int)
997 {
998 	Flush(STATUS_STREAM);
999 	Flush(DEBUG_STREAM);
1000 
1001 	FileMessage(WARNING_STREAM, msg);
1002 }
1003 
Error(POVMSObjectPtr msg,POVMSObjectPtr,int)1004 void MessageOutput::Error(POVMSObjectPtr msg, POVMSObjectPtr, int)
1005 {
1006 	Flush(STATUS_STREAM);
1007 	Flush(DEBUG_STREAM);
1008 
1009 	FileMessage(WARNING_STREAM, msg);
1010 }
1011 
FatalError(POVMSObjectPtr msg,POVMSObjectPtr,int)1012 void MessageOutput::FatalError(POVMSObjectPtr msg, POVMSObjectPtr, int)
1013 {
1014 	int ret = kNoErr;
1015 	int l = 0;
1016 	int s = 0;
1017 
1018 	Flush(STATUS_STREAM);
1019 	Flush(DEBUG_STREAM);
1020 
1021 	if(ret == kNoErr)
1022 		FileMessage(FATAL_STREAM, msg);
1023 
1024 	if(ret != kNoErr)
1025 		throw ret;
1026 }
1027 
DebugInfo(POVMSObjectPtr msg,POVMSObjectPtr,int)1028 void MessageOutput::DebugInfo(POVMSObjectPtr msg, POVMSObjectPtr, int)
1029 {
1030 	int ret = kNoErr;
1031 	int l = 0;
1032 
1033 	Flush(STATUS_STREAM);
1034 
1035 	l = output_string_buffer_size;
1036 	output_string_buffer[0] = 0;
1037 	ret = POVMSUtil_GetString(msg, kPOVAttrib_EnglishText, output_string_buffer, &l);
1038 	if(ret == kNoErr)
1039 		Printf(DEBUG_STREAM, "%s\n", output_string_buffer);
1040 
1041 	if(ret != kNoErr)
1042 		throw ret;
1043 }
1044 
FileMessage(int stream,POVMSObjectPtr msg)1045 void MessageOutput::FileMessage(int stream, POVMSObjectPtr msg)
1046 {
1047 	POVMSLong ll = 0;
1048 	int ret = kNoErr;
1049 	int l = 0;
1050 
1051 	l = output_string_buffer_size;
1052 	output_string_buffer[0] = 0;
1053 	if(POVMSUtil_GetString(msg, kPOVAttrib_FileName, output_string_buffer, &l) == kNoErr)
1054 	{
1055 		if((POVMSUtil_GetInt(msg, kPOVAttrib_Line, &l) == kNoErr) && ((stream == WARNING_STREAM) || (stream == FATAL_STREAM)))
1056 		{
1057 			if((strlen(output_string_buffer) > 0) && (l > 0))
1058 				Printf(stream, "File: %s  Line: %d\n", output_string_buffer, l);
1059 		}
1060 		if(((POVMSUtil_GetLong(msg, kPOVAttrib_FilePosition, &ll) == kNoErr) && (Num_Echo_Lines > 0)) && (stream == FATAL_STREAM))
1061 		{
1062 			Printf(stream, "File Context (%d lines):\n", Num_Echo_Lines);
1063 			Printfile(stream, output_string_buffer, ll, -Num_Echo_Lines);
1064 			Printf(stream, "\n");
1065 		}
1066 	}
1067 
1068 	l = output_string_buffer_size;
1069 	output_string_buffer[0] = 0;
1070 	ret = POVMSUtil_GetString(msg, kPOVAttrib_EnglishText, output_string_buffer, &l);
1071 	if(ret == kNoErr)
1072 		Printf(stream, "%s\n", output_string_buffer);
1073 
1074 	if(ret != kNoErr)
1075 		throw ret;
1076 }
1077 
GetOptionSwitchString(POVMSObjectPtr msg,POVMSType key,bool defaultstate)1078 const char *MessageOutput::GetOptionSwitchString(POVMSObjectPtr msg, POVMSType key, bool defaultstate)
1079 {
1080 	POVMSBool b = false;
1081 
1082 	if(POVMSUtil_GetBool(msg, key, &b) != kNoErr)
1083 		b = defaultstate;
1084 
1085 	if(b == true)
1086 		return ".On ";
1087 
1088 	return ".Off";
1089 }
1090 
1091 END_POV_FRONTEND_NAMESPACE
1092