Line data Source code
1 : /* Copyright (C) 2011 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "CommonConvert.h"
21 : #include "PMDConvert.h"
22 : #include "PSAConvert.h"
23 : #include "StdSkeletons.h"
24 :
25 : #include <cstdarg>
26 : #include <cassert>
27 :
28 0 : void default_logger(void*, int severity, const char* message)
29 : {
30 0 : fprintf(stderr, "[%d] %s\n", severity, message);
31 0 : }
32 :
33 : static LogFn g_Logger = &default_logger;
34 : static void* g_LoggerCBData = NULL;
35 :
36 16 : EXPORT void set_logger(LogFn logger, void* cb_data)
37 : {
38 16 : if (logger)
39 : {
40 11 : g_Logger = logger;
41 11 : g_LoggerCBData = cb_data;
42 : }
43 : else
44 : {
45 5 : g_Logger = &default_logger;
46 5 : g_LoggerCBData = NULL;
47 : }
48 16 : }
49 :
50 39 : void Log(int severity, const char* msg, ...)
51 : {
52 : char buffer[1024];
53 : va_list ap;
54 39 : va_start(ap, msg);
55 39 : vsnprintf(buffer, sizeof(buffer), msg, ap);
56 39 : buffer[sizeof(buffer)-1] = '\0';
57 39 : va_end(ap);
58 :
59 39 : g_Logger(g_LoggerCBData, severity, buffer);
60 39 : }
61 :
62 : struct BufferedOutputCallback : public OutputCB
63 : {
64 : static const unsigned int bufferSize = 4096;
65 : char buffer[bufferSize];
66 : unsigned int bufferUsed;
67 :
68 : OutputFn fn;
69 : void* cb_data;
70 :
71 5 : BufferedOutputCallback(OutputFn fn, void* cb_data)
72 5 : : fn(fn), cb_data(cb_data), bufferUsed(0)
73 : {
74 5 : }
75 :
76 5 : ~BufferedOutputCallback()
77 10 : {
78 : // flush the buffer if it's not empty
79 5 : if (bufferUsed > 0)
80 4 : fn(cb_data, buffer, bufferUsed);
81 5 : }
82 :
83 2482 : virtual void operator() (const char* data, unsigned int length)
84 : {
85 2482 : if (bufferUsed+length > bufferSize)
86 : {
87 : // will overflow buffer, so flush the buffer first
88 3 : fn(cb_data, buffer, bufferUsed);
89 3 : bufferUsed = 0;
90 :
91 3 : if (length > bufferSize)
92 : {
93 : // new data won't fit in buffer, so send it out unbuffered
94 0 : fn(cb_data, data, length);
95 0 : return;
96 : }
97 : }
98 :
99 : // append onto buffer
100 2482 : memcpy(buffer+bufferUsed, data, length);
101 2482 : bufferUsed += length;
102 2482 : assert(bufferUsed <= bufferSize);
103 : }
104 : };
105 :
106 5 : int convert_dae_to_whatever(const char* dae, OutputFn writer, void* cb_data, void(*conv)(const char*, OutputCB&, std::string&))
107 : {
108 5 : Log(LOG_INFO, "Starting conversion");
109 :
110 5 : FCollada::Initialize();
111 :
112 10 : std::string xmlErrors;
113 10 : BufferedOutputCallback cb(writer, cb_data);
114 : try
115 : {
116 5 : conv(dae, cb, xmlErrors);
117 : }
118 2 : catch (const ColladaException& e)
119 : {
120 1 : if (! xmlErrors.empty())
121 1 : Log(LOG_ERROR, "%s", xmlErrors.c_str());
122 :
123 1 : Log(LOG_ERROR, "%s", e.what());
124 :
125 1 : FCollada::Release();
126 :
127 1 : return -2;
128 : }
129 :
130 4 : FCollada::Release();
131 :
132 4 : if (! xmlErrors.empty())
133 : {
134 0 : Log(LOG_ERROR, "%s", xmlErrors.c_str());
135 :
136 0 : return -1;
137 : }
138 :
139 4 : return 0;
140 : }
141 :
142 5 : EXPORT int convert_dae_to_pmd(const char* dae, OutputFn pmd_writer, void* cb_data)
143 : {
144 5 : return convert_dae_to_whatever(dae, pmd_writer, cb_data, ColladaToPMD);
145 : }
146 :
147 0 : EXPORT int convert_dae_to_psa(const char* dae, OutputFn psa_writer, void* cb_data)
148 : {
149 0 : return convert_dae_to_whatever(dae, psa_writer, cb_data, ColladaToPSA);
150 : }
151 :
152 6 : EXPORT int set_skeleton_definitions(const char* xml, int length)
153 : {
154 12 : std::string xmlErrors;
155 : try
156 : {
157 6 : Skeleton::LoadSkeletonDataFromXml(xml, length, xmlErrors);
158 : }
159 2 : catch (const ColladaException& e)
160 : {
161 1 : if (! xmlErrors.empty())
162 1 : Log(LOG_ERROR, "%s", xmlErrors.c_str());
163 :
164 1 : Log(LOG_ERROR, "%s", e.what());
165 :
166 1 : return -1;
167 : }
168 :
169 5 : return 0;
170 : }
|