d846e9ae83c08a593ed2dacaa02d900487a11f09
[blender.git] / source / gameengine / GamePlayer / common / GPC_Engine.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program 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 this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/GamePlayer/common/GPC_Engine.cpp
29  *  \ingroup player
30  */
31
32
33 #ifdef WIN32
34         #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
35 #endif // WIN32
36
37 #include <iostream>
38
39 #include "BKE_blender.h"  // initglobals()
40 #include "BKE_global.h"  // Global G
41 #include "BKE_report.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_camera_types.h"  // Camera
44 #include "DNA_object_types.h"  // Object
45
46 #include "BLO_readfile.h"
47 #include "BLI_blenlib.h"
48
49 // include files needed by "KX_BlenderSceneConverter.h"
50
51 #include "CTR_Map.h"
52 #include "SCA_IActuator.h"
53 #include "RAS_MeshObject.h"
54
55 #include "KX_BlenderSceneConverter.h"
56 #include "KX_KetsjiEngine.h"
57 #include "NG_LoopBackNetworkDeviceInterface.h"
58
59 #include "RAS_IRenderTools.h"
60
61 #include "GPC_Engine.h"
62 #include "GPC_KeyboardDevice.h"
63 #include "GPC_MouseDevice.h"
64 #include "GPC_RawImage.h"
65 #include "GPC_RawLoadDotBlendArray.h"
66
67
68
69 GPC_Engine::GPC_Engine(char *customLoadingAnimationURL,
70                 int foregroundColor, int backgroundColor, int frameRate) :
71                 m_initialized(false), m_running(false), m_loading(false),
72                 m_customLoadingAnimation(false), m_previousProgress(0.0),
73                 m_system(NULL), m_keyboarddev(NULL),
74                 m_mousedev(NULL), m_canvas(NULL), m_rendertools(NULL),
75                 m_portal(NULL), m_sceneconverter(NULL), m_networkdev(NULL),
76                 m_curarea(NULL), m_customLoadingAnimationURL(NULL),
77                 m_foregroundColor(foregroundColor), m_backgroundColor(backgroundColor),
78                 m_frameRate(frameRate),
79                 m_BlenderLogo(0), m_Blender3DLogo(0)/*, m_NaNLogo(0)*/
80 {
81         if(customLoadingAnimationURL[0] != '\0')
82         {
83                 m_customLoadingAnimationURL = new char[sizeof(customLoadingAnimationURL)];
84 // not yet, need to be implemented first...             m_customLoadingAnimation = true;
85         }
86
87         // load the Blender logo into memory
88         m_BlenderLogo = new GPC_RawImage();
89         // blender3d size is 115 x 32 so make resulting texture 128 x 128
90         if(!m_BlenderLogo->Load("BlenderLogo", 128, 128, GPC_RawImage::alignTopLeft, 8, 8))
91                 m_BlenderLogo = 0;
92
93         // load the Blender3D logo into memory
94         m_Blender3DLogo = new GPC_RawImage();
95         // blender3d size is 136 x 11 so make resulting texture 256 x 256
96         if(!m_Blender3DLogo->Load("Blender3DLogo", 256, 256, GPC_RawImage::alignBottomRight, 8, 8))
97                 m_Blender3DLogo = 0;
98
99 #if 0
100         // obsolete logo
101         // load the NaN logo into memory
102         m_NaNLogo = new GPC_RawImage();
103         // blender3d size is 32 x 31 so make resulting texture 64 x 64
104         if(!m_NaNLogo->Load("NaNLogo", 64, 64, GPC_RawImage::alignBottomRight, 8, 8))
105                 m_NaNLogo = 0;
106 #endif
107 }
108
109
110 GPC_Engine::~GPC_Engine()
111 {
112         // deleting everything in reverse order of creation
113 #if 0
114 // hmm deleted in Stop()        delete m_portal;
115 // hmm deleted in Stop()        delete m_sceneconverter;
116         delete m_system;
117         delete m_networkdev;
118         delete m_rendertools;
119         delete m_canvas;
120         delete m_mousedev;
121         delete m_keyboarddev;
122 // not yet used so be careful and not delete them
123 //      delete m_WaveCache;
124 //      delete m_curarea;  // for future use, not used yet
125 #endif
126         delete m_BlenderLogo;
127         delete m_Blender3DLogo;
128 #if 0
129         delete m_NaNLogo;
130 #endif
131 }
132
133
134 bool GPC_Engine::Start(char *filename)
135 {
136         ReportList reports;
137         BlendFileData *bfd;
138         
139         BKE_reports_init(&reports, RPT_STORE);
140         bfd= BLO_read_from_file(filename, &reports);
141         BKE_reports_clear(&reports);
142
143         if (!bfd) {
144                         // XXX, deal with error here
145                 cout << "Unable to load: " << filename << endl;
146                 return false;
147         }
148
149         StartKetsji();
150
151         if(bfd->type == BLENFILETYPE_PUB)
152                 m_canvas->SetBannerDisplayEnabled(false);
153
154         return true;
155 }
156
157
158 bool GPC_Engine::Start(unsigned char *blenderDataBuffer,
159                 unsigned int blenderDataBufferSize)
160 {
161         ReportList reports;
162         BlendFileData *bfd;
163         
164         BKE_reports_init(&reports, RPT_STORE);
165         bfd= BLO_read_from_memory(blenderDataBuffer, blenderDataBufferSize, &reports);
166         BKE_reports_clear(&reports);
167
168         if (!bfd) {
169                         // XXX, deal with error here
170                 cout << "Unable to load. " << endl;
171                 return false;
172         }
173         
174         StartKetsji();
175
176         if(bfd->type == BLENFILETYPE_PUB)
177                 m_canvas->SetBannerDisplayEnabled(false);
178
179         return true;
180 }
181
182
183 bool GPC_Engine::StartKetsji(void)
184 {
185         STR_String startSceneName = ""; // XXX scene->id.name + 2;
186 /*
187         KX_KetsjiEngine* ketsjieng = new KX_KetsjiEngine(m_system);
188         m_portal = new KetsjiPortal(ketsjieng);
189         m_portal->setSecurity(psl_Highest);
190                 
191         KX_ISceneConverter *sceneconverter = new KX_BlenderSceneConverter(&G, ketsjieng);
192                 
193         m_portal->Enter(
194                         startSceneName,
195                         sceneconverter,
196                         m_canvas,
197                         m_rendertools,
198                         m_keyboarddev,
199                         m_mousedev,
200                         m_networkdev,
201                         m_system);
202
203         m_system->SetMainLoop(m_portal->m_ketsjieng);
204
205         m_running = true;
206         */
207         return true;
208 }
209
210
211 void GPC_Engine::StartLoadingAnimation()
212 {
213         if(m_customLoadingAnimation)
214         {
215         }
216         else
217         {
218                 unsigned char *blenderDataBuffer;
219                 int blenderDataBufferSize;
220                 GetRawLoadingAnimation(&blenderDataBuffer, &blenderDataBufferSize);
221                 if(!Start(blenderDataBuffer, blenderDataBufferSize))
222                         cout << "something went wrong when starting the engine" << endl;
223                 delete blenderDataBuffer;  // created with 'new' in GetRawLoadingAnimation()
224         }
225 }
226
227         
228 // will be platform dependant
229 float GPC_Engine::DetermineProgress(void)
230 {
231 #if 0
232         float progress;
233         if ((m_blenderData.m_ulProgress > 0) &&
234                         (m_blenderData.m_ulProgressMax != m_blenderData.m_ulProgress)) {
235                 progress = (float)m_blenderData.m_ulProgress;
236                 progress /= (float)m_blenderData.m_ulProgressMax;
237         }
238         else {
239                 progress = 0.f;
240         }
241         progress *= 100.f;
242         return (unsigned int) progress ;
243 #endif
244         return m_previousProgress + 0.01;  // temporary TODO
245 }
246
247         
248 void GPC_Engine::UpdateLoadingAnimation(void)
249 {
250         //int delta;
251
252         float progress = DetermineProgress();
253
254         if(progress > m_previousProgress)
255         {
256 //              delta = progress - m_previousProgress;
257                 m_previousProgress = progress;
258                 if(m_previousProgress > 1.0)
259                         m_previousProgress = 1.0;  // limit to 1.0 (has to change !)
260 //                      m_engine->m_previousProgress = 0.0;
261         }
262
263         STR_String to = "";
264         STR_String from = "";
265         STR_String subject = "progress";
266         STR_String body;
267         body.Format("%f", progress);  // a number between 0.0 and 1.0
268
269         if(m_networkdev)
270         {
271                 // Store a progress message in the network device.
272                 NG_NetworkMessage* msg = new NG_NetworkMessage(to, from, subject, body);
273                 m_networkdev->SendNetworkMessage(msg);
274                 msg->Release();
275         }
276 }
277
278
279 void GPC_Engine::Stop()
280 {
281         // only delete things that are created in StartKetsji()
282 /*      if(m_portal)
283         {
284                 m_portal->Leave();
285                 delete m_portal;  // also gets rid of KX_KetsjiEngine (says Maarten)
286                 m_portal = 0;
287         }
288 */      if(m_sceneconverter)
289         {
290                 delete m_sceneconverter;
291                 m_sceneconverter = 0;
292         }
293 #if 0
294         if(m_frameTimerID)
295         {
296                 ::KillTimer(0, m_frameTimerID);
297                 m_frameTimerID = 0;
298         }
299         m_engineRunning = false;
300 #endif
301
302         m_running = false;
303 }
304
305
306 void GPC_Engine::Exit()
307 {
308         if(m_running)
309                 Stop();
310
311         if (m_system) {
312                 delete m_system;
313                 m_system = 0;
314         }
315         if (m_keyboarddev) {
316                 delete m_keyboarddev;
317                 m_keyboarddev = 0;
318         }
319         if (m_mousedev) {
320                 delete m_mousedev;
321                 m_mousedev = 0;
322         }
323         if (m_canvas) {
324                 delete m_canvas;
325                 m_canvas = 0;
326         }
327         if (m_rendertools) {
328                 delete m_rendertools;
329                 m_rendertools = 0;
330         }
331         if (m_networkdev) {
332                 delete m_networkdev;
333                 m_networkdev = 0;
334         }
335
336         m_initialized = false;
337 }
338