1 #include "EndLevelScoreScreen.h"
2 #include "../../GameApp/BaseGameApp.h"
3 #include "../../Resource/Loaders/PalLoader.h"
4 #include "../../Resource/Loaders/PcxLoader.h"
5 #include "../../Resource/Loaders/PidLoader.h"
6 #include "../../Graphics2D/Image.h"
7
8 #include "../../Actor/ActorTemplates.h"
9 #include "../../Actor/Actor.h"
10 #include "../../Actor/Components/PositionComponent.h"
11
12 #include "ScoreScreenProcesses.h"
13
14 //=================================================================================================
15 //
16 // Global variables
17 //
18 //=================================================================================================
19
20 static Point g_ScreenScale(1.0, 1.0);
21
22 uint8_t g_ScoreScreenPalette[] =
23 {
24 0x00, 0x00, 0x00, // 0
25 255, 252, 202, // 1 - DONE
26 240, 238, 90, // 2 - DONE
27 223, 220, 76, // 3 - DONE
28 219, 217, 74, // 4 - DONE
29 210, 208, 72, // 5 - DONE
30 189, 187, 63, // 6 - DONE
31 154, 153, 52, // 7 - DONE
32 130, 115, 44, // 8 - DONE
33 98, 97, 33, // 9 - DONE
34 64, 63, 21, // 10 - DONE
35 41, 41, 14, // 11 - DONE
36 38, 35, 44, // 12 - DONE
37 13, 11, 113, // 13 - DONE
38 19, 19, 170, // 14 - DONE
39 0, 104, 144, // 15 - DONE
40 178, 187, 188, // 16 - DONE
41 18, 157, 18, // 17 - DONE
42 75, 74, 68, // 18 - DONE
43 112, 111, 105, // 19 - DONE
44 220, 96, 0, // 20 - DONE
45 99, 4, 0, // 21 - DONE
46 138, 138, 138, // 22 - DONE
47 125, 41, 0, // 23 - DONE
48 44, 44, 44, // 24 - DONE
49 53, 6, 0, // 25 - DONE
50 253, 247, 202, // 26 - DONE
51 0xFE, 0xF4, 0x91, // 27 - DONE
52 252, 236, 67, // 28 - DONE
53 247, 232, 11, // 29 - DONE
54 240, 212, 95, // 30 - DONE
55 224, 183, 31, // 31 - DONE
56 205, 156, 15, // 32 - DONE
57 190, 134, 18, // 33 - DONE
58 250, 238, 140, // 34 - DONE
59 239, 222, 97, // 35 - DONE
60 217, 201, 90, // 36 - DONE
61 194, 179, 78, // 37 - DONE
62 161, 149, 65, // 38 - DONE
63 129, 119, 52, // 39 - DONE
64 91, 0, 18, // 40 - DONE
65 251, 221, 29, // 41 - DONE
66 247, 227, 121, // 42 - DONE
67 219, 136, 15, // 43 - DONE
68 171, 73, 9, // 44 - DONE
69 125, 38, 17, // 45 - DONE
70 219, 217, 254, // 46 - DONE
71 143, 137, 251, // 47 - DONE
72 45, 40, 218, // 48 - DONE
73 7, 6, 182, // 49 - DONE
74 172, 251, 203, // 50 - DONE
75 21, 233, 60, // 51 - DONE
76 0, 158, 0, // 52 - DONE
77 0, 48, 0, // 53 - DONE
78 243, 199, 254, // 54 - DONE
79 0xFF, 0x00, 0xFF, // 55 55
80 0x5B, 0x5F, 0xFF, // 56 56
81 0x97, 0x9C, 0xFF, // 57 57
82 254, 193, 194, // 58 - DONE
83 253, 56, 57, // 59 - DONE
84 247, 2, 3, // 60 - DONE
85 146, 11, 24, // 61 - DONE
86 250, 222, 109, // 62 - DONE
87 251, 239, 191, // 63 - DONE
88 242, 198, 81, // 64 - DONE
89 243, 187, 48, // 65 - DONE
90 205, 138, 15, // 66 - DONE
91 232, 152, 13, // 67 - DONE
92 157, 101, 24, // 68 - DONE
93 221, 150, 53, // 69 - DONE
94 199, 138, 57, // 70 - DONE
95 196, 112, 25, // 71 - DONE
96 143, 67, 10, // 72 - DONE
97 79, 36, 5, // 73 - DONE
98 0, 255, 156, // 74 - DONE
99 8, 48, 121, // 75 - DONE
100 255, 0, 255, // 76 - DONE
101 90, 10, 59, // 77 - DONE
102 250, 234, 152, // 78 - DONE
103 241, 188, 0, // 79 - DONE
104 238, 189, 37, // 80 - DONE
105 209, 117, 5, // 81 - DONE
106 145, 72, 6, // 82 - DONE
107 11, 174, 11, // 83 - DONE
108 127, 211, 129, // 84 - DONE
109 112, 50, 3, // 85 - DONE
110 9, 86, 0, // 86 - DONE
111 70, 208, 46, // 87 - DONE
112 0xF9, 0xDB, 0x42, // 88 88
113 232, 251, 212, // 89 - DONE
114 86, 219, 212, // 90 - DONE
115 0xF0, 0x58, 0x02, // 91
116 34, 96, 250, // 92 - DONE
117 18, 100, 28, // 93 - DONE
118 55, 157, 56, // 94 - DONE
119 7, 52, 3, // 95 - DONE
120 120, 208, 110, // 96 - DONE
121 192, 109, 134, // 97 - DONE
122 197, 45, 93, // 98 - DONE
123 145, 18, 58, // 99 - DONE
124 95, 64, 28, // 100 - DONE
125 110, 74, 32, // 101 - DONE
126 18, 8, 43, // 102 - DONE
127 41, 0, 0, // 103 - DONE
128 106, 57, 8, // 104 - DONE
129 0xF3, 0xC3, 0x4D, // 105
130 0xF4, 0xD7, 0x5C, // 106
131 0xD7, 0xA8, 0x18, // 107
132 115, 90, 41, // 108 - DONE
133 115, 82, 33, // 109 - DONE
134 115, 75, 24, // 110 - DONE
135 114, 75, 16, // 111 - DONE
136 112, 66, 14, // 112 - DONE
137 109, 57, 16, // 113 - DONE
138 0x9A, 0x11, 0xC5, // 114 114
139 0x05, 0xFF, 0xA1, // 115 115
140 108, 49, 9, // 116 - DONE
141 99, 49, 16, // 117 - DONE
142 0xEC, 0x75, 0xFF, // 118 118
143 0xF8, 0x9F, 0xFF, // 119 119
144 90, 49, 5, // 120 - DONE
145 100, 41, 5, // 121 - DONE
146 90, 41, 8, // 122 - DONE
147 90, 41, 0, // 123 - DONE
148 81, 42, 8, // 124 - DONE
149 0xBC, 0x08, 0x7D, // 125 125
150 91, 32, 2, // 126 - DONE
151 80, 33, 8, // 127 - DONE
152 82, 33, 0, // 128 - DONE
153 0x9A, 0x53, 0x16, // 129 129
154 0x90, 0x40, 0x0D, // 130 130
155 82, 24, 0, // 131 - DONE
156 79, 24, 8, // 132 - DONE
157 74, 24, 0, // 133 - DONE
158 65, 24, 0, // 134 - DONE
159 75, 16, 0, // 135 - DONE
160 61, 16, 0, // 136 - DONE
161 43, 15, 0, // 137 - DONE
162 0xD4, 0x03, 0xC8, // 138 138
163 0xB8, 0x06, 0xAB, // 139 139
164 0x9C, 0x0C, 0x83, // 140 140
165 0x79, 0x05, 0x73, // 141 141
166 0x68, 0x03, 0x65, // 142 142
167 0x52, 0x00, 0x5B, // 143 143
168 0x9A, 0x9B, 0x9B, // 144 144
169 0xAB, 0xAB, 0xAB, // 145 145
170 0x47, 0x30, 0x13, // 146 146
171 0x5D, 0x3C, 0x14, // 147 147
172 0x71, 0x4B, 0x14, // 148 148
173 0x69, 0x42, 0x1D, // 149 149
174 0x51, 0x32, 0x14, // 150 150
175 10, 10, 10, // 151 - DONE
176 9, 9, 9, // 152 - DONE
177 0x38, 0x2E, 0x2E, // 153 153
178 0x61, 0x53, 0x48, // 154 154
179 0x88, 0x79, 0x60, // 155 155
180 130, 130, 130, // 156 - DONE
181 0xBC, 0x74, 0x83, // 157 157
182 100, 100, 100, // 158 - DONE
183 0x5E, 0x3E, 0x71, // 159 159
184 0x03, 0x21, 0x36, // 160 160
185 77, 77, 77, // 161 - DONE
186 0x03, 0x4F, 0x74, // 162 START
187 0x03, 0x59, 0x7F, // 163
188 58, 58, 58, // 164 - DONE
189 0x03, 0x75, 0xA3, // 165
190 0x03, 0x85, 0xBB, // 166
191 0x03, 0x94, 0xC3, // 167
192 0x00, 0x27, 0x4E, // 168
193 8, 8, 8, // 169 - DONE
194 114, 70, 88, // 170 - DONE
195 0x03, 0x03, 0x03, // 171
196 0x57, 0xA9, 0xC1, // 172
197 0x3F, 0x88, 0xA8, // 173
198 0x24, 0x56, 0x79, // 174
199 0x18, 0x39, 0x54, // 175
200 0x11, 0x25, 0x37, // 176 END
201 123, 132, 0, // 177 - DONE
202 97, 97, 7, // 178 - DONE
203 102, 91, 23, // 179 - DONE
204 137, 118, 32, // 180 - DONE
205 186, 176, 141, // 181 - DONE
206 134, 103, 3, // 182 - DONE
207 0x03, 0x07, 0x0B, // 183 183
208 0x02, 0x05, 0x08, // 184 184
209 148, 90, 0, // 185 - DONE
210 0x00, 0x01, 0x02, // 186 186
211 214, 135, 30, // 187 - DONE
212 240, 154, 52, // 188 - DONE
213 0x66, 0x0F, 0x08, // 189 189
214 215, 123, 26, // 190 - DONE
215 192, 109, 22, // 191 - DONE
216 214, 129, 41, // 192 - DONE
217 206, 109, 13, // 193 - DONE
218 221, 145, 71, // 194 - DONE
219 179, 91, 6, // 195 - DONE
220 241, 139, 41, // 196 - DONE
221 214, 110, 13, // 197 - DONE
222 236, 127, 30, // 198 - DONE
223 189, 92, 7, // 199 - DONE
224 206, 110, 26, // 200 - DONE
225 214, 111, 26, // 201 - DONE
226 210, 123, 51, // 202 - DONE
227 226, 112, 21, // 203 - DONE
228 202, 93, 7, // 204 - DONE
229 178, 82, 7, // 205 - DONE
230 201, 111, 41, // 206 - DONE
231 135, 99, 71, // 207 - DONE
232 170, 74, 0, // 208 - DONE
233 178, 86, 16, // 209 - DONE
234 189, 89, 16, // 210 - DONE
235 182, 91, 24, // 211 - DONE
236 154, 67, 5, // 212 - DONE
237 198, 92, 16, // 213 - DONE
238 189, 82, 7, // 214 - DONE
239 228, 113, 33, // 215 - DONE
240 170, 74, 8, // 216 - DONE
241 210, 94, 16, // 217 - DONE
242 198, 96, 27, // 218 - DONE
243 168, 66, 0, // 219 - DONE
244 178, 93, 38, // 220 - DONE
245 155, 115, 89, // 221 - DONE
246 212, 97, 25, // 222 - DONE
247 185, 74, 6, // 223 - DONE
248 143, 73, 30, // 224 - DONE
249 136, 50, 0, // 225 - DONE
250 170, 74, 19, // 226 - DONE
251 168, 66, 8, // 227 - DONE
252 152, 54, 0, // 228 - DONE
253 135, 51, 8, // 229 - DONE
254 189, 74, 17, // 230 - DONE
255 103, 34, 0, // 231 - DONE
256 125, 41, 0, // 232 - DONE
257 168, 66, 17, // 233 - DONE
258 152, 54, 8, // 234 - DONE
259 185, 62, 8, // 235 - DONE
260 167, 54, 5, // 236 - DONE
261 144, 41, 0, // 237 - DONE
262 87, 24, 0, // 238 - DONE
263 134, 51, 19, // 239 - DONE
264 68, 18, 0, // 240 - DONE
265 115, 30, 0, // 241 - DONE
266 129, 32, 0, // 242 - DONE
267 129, 38, 8, // 243 - DONE
268 103, 24, 0, // 244 - DONE
269 96, 31, 15, // 245 - DONE
270 82, 15, 0, // 246 - DONE
271 94, 16, 0, // 247 - DONE
272 61, 25, 20, // 248 - DONE
273 69, 8, 0, // 249 - DONE
274 53, 6, 0, // 250 - DONE
275 34, 3, 0, // 251 - DONE
276 0x00, 0x53, 0x98, // 252 252
277 8, 0, 0, // 253 - DONE
278 123, 49, 49, // 254 - DONE
279 0xFF, 0xFF, 0xFF, // 255 255
280 };
281
282 //=================================================================================================
283 //
284 // Global helper functions
285 //
286 //=================================================================================================
287
GetScreenRect()288 static SDL_Rect GetScreenRect()
289 {
290 Point windowSize = g_pApp->GetWindowSize();
291 Point scale = g_pApp->GetScale();
292 int targetWidth = (int)(windowSize.x / scale.x);
293 int targetHeight = (int)(windowSize.y / scale.y);
294
295 return{ 0, 0, targetWidth, targetHeight };
296 }
297
298 //=================================================================================================
299 //
300 // Events bound to this module
301 //
302 //=================================================================================================
303
304 class EventData_ScoreScreen_Finished_Intro : public BaseEventData
305 {
306 public:
307 static const EventType sk_EventType;
308
EventData_ScoreScreen_Finished_Intro()309 EventData_ScoreScreen_Finished_Intro() { }
310
VGetEventType(void) const311 virtual const EventType& VGetEventType(void) const { return sk_EventType; }
VCopy() const312 virtual IEventDataPtr VCopy() const
313 {
314 return IEventDataPtr(new EventData_ScoreScreen_Finished_Intro());
315 }
VSerialize(std::ostringstream & out) const316 virtual void VSerialize(std::ostringstream& out) const { assert(false && "Cannot be serialized"); }
VDeserialize(std::istringstream & in)317 virtual void VDeserialize(std::istringstream& in) { assert(false && "Cannot be serialized"); }
318
GetName(void) const319 virtual const char* GetName(void) const { return "EventData_ScoreScreen_Finished_Intro"; }
320 };
321
322 const EventType EventData_ScoreScreen_Finished_Intro::sk_EventType(0xb71eff5b);
323
324 //=================================================================================================
325 //
326 // ScreenElementScoreScreen
327 //
328 //=================================================================================================
329
ScreenElementScoreScreen(SDL_Renderer * pRenderer)330 ScreenElementScoreScreen::ScreenElementScoreScreen(SDL_Renderer* pRenderer)
331 :
332 Scene(pRenderer),
333 m_pBackground(nullptr),
334 m_pRenderer(pRenderer),
335 m_bInScoreScreen(false),
336 m_State(ScoreScreenState_None),
337 m_NextLevelNumber(0),
338 m_ScorePointsOnLevelStart(0),
339 m_ScorePointsCollectedInLevel(0),
340 m_DisplayedLevelScore(0),
341 m_DisplayedGameScore(0)
342 {
343 IEventMgr::Get()->VAddListener(MakeDelegate(this, &ScreenElementScoreScreen::FinishedLoadingRowDelegate), EventData_Finished_Loading_Row::sk_EventType);
344 IEventMgr::Get()->VAddListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenFinishedIntroDelegate), EventData_ScoreScreen_Finished_Intro::sk_EventType);
345 IEventMgr::Get()->VAddListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenLevelScoreAddedDelegate), EventData_ScoreScreen_Level_Score_Added::sk_EventType);
346 }
347
~ScreenElementScoreScreen()348 ScreenElementScoreScreen::~ScreenElementScoreScreen()
349 {
350 IEventMgr::Get()->VRemoveListener(MakeDelegate(this, &ScreenElementScoreScreen::FinishedLoadingRowDelegate), EventData_Finished_Loading_Row::sk_EventType);
351 IEventMgr::Get()->VRemoveListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenFinishedIntroDelegate), EventData_ScoreScreen_Finished_Intro::sk_EventType);
352 IEventMgr::Get()->VRemoveListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenLevelScoreAddedDelegate), EventData_ScoreScreen_Level_Score_Added::sk_EventType);
353
354 m_SpawnRowProcessList.clear();
355
356 SAFE_DELETE(m_pProcessMgr);
357
358 g_pApp->SetScale(m_OriginalScale);
359 }
360
VOnUpdate(uint32 msDiff)361 void ScreenElementScoreScreen::VOnUpdate(uint32 msDiff)
362 {
363 m_pProcessMgr->UpdateProcesses(msDiff);
364
365 Scene::OnUpdate(msDiff);
366 }
367
VOnRender(uint32 msDiff)368 void ScreenElementScoreScreen::VOnRender(uint32 msDiff)
369 {
370 assert(m_pBackground != nullptr);
371
372 SDL_Rect backgroundRect = GetScreenRect();
373 SDL_RenderCopy(m_pRenderer, m_pBackground->GetTexture(), &backgroundRect, NULL);
374 //LOG("Rendered. Image width: " + ToStr(m_pBackground->GetWidth()));
375
376 Scene::OnRender();
377 }
378
VOnEvent(SDL_Event & evt)379 bool ScreenElementScoreScreen::VOnEvent(SDL_Event& evt)
380 {
381 switch (evt.type)
382 {
383 case SDL_KEYDOWN:
384 {
385 if (evt.key.repeat == 0)
386 {
387 if (SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_KP_ENTER ||
388 SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_RETURN ||
389 SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_SPACE ||
390 SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_ESCAPE)
391 {
392 ForceNextState();
393 return true;
394 }
395 }
396 break;
397 }
398 }
399
400 return false;
401 }
402
ForceNextState()403 void ScreenElementScoreScreen::ForceNextState()
404 {
405 if (m_State == ScoreScreenState_Intro)
406 {
407 // Kill all pending processes
408 m_pProcessMgr->AbortAllProcesses(true);
409
410 // Force transition
411 IEventDataPtr pFinishedIntroEvent(new EventData_ScoreScreen_Finished_Intro());
412 IEventMgr::Get()->VTriggerEvent(pFinishedIntroEvent);
413 }
414 else if (m_State == ScoreScreenState_SpawningScoreRows)
415 {
416 // Force all rows to spawn process
417 for (auto iter = m_ScoreRowList.begin(); iter != m_ScoreRowList.end();)
418 {
419 StrongProcessPtr pRowProcess(new SpawnScoreRowProcess((*iter)));
420 m_pProcessMgr->AttachProcess(pRowProcess);
421
422 m_SpawnRowProcessList.push_back(pRowProcess);
423
424 iter = m_ScoreRowList.erase(iter);
425 }
426
427 // And force them to finish immediately
428 for (StrongProcessPtr pProc : m_SpawnRowProcessList)
429 {
430 if (SpawnScoreRowProcess* pSpawnRowProc = dynamic_cast<SpawnScoreRowProcess*>(pProc.get()))
431 {
432 pSpawnRowProc->ForceSpawnImmediately();
433 }
434 else
435 {
436 assert(false && "Could not cast");
437 }
438 }
439
440 m_State = ScoreScreenState_Finished;
441 }
442 else if (m_State == ScoreScreenState_Finished)
443 {
444 // Dissolve rows
445 for (StrongProcessPtr pProc : m_SpawnRowProcessList)
446 {
447 if (SpawnScoreRowProcess* pSpawnRowProc = dynamic_cast<SpawnScoreRowProcess*>(pProc.get()))
448 {
449 // Dissolve row
450 }
451 else
452 {
453 assert(false && "Could not cast");
454 }
455 }
456
457 // Load next level and wait for death
458 LoadNextLevel();
459
460 m_State = ScoreScreenState_Exiting;
461 }
462 else if (m_State == ScoreScreenState_Exiting)
463 {
464 // Nothing to do here, really
465 }
466 else
467 {
468 LOG_ERROR("Invalid state: " + ToStr((int)m_State));
469 assert(false && "Invalid state");
470 }
471 }
472
LoadNextLevel()473 void ScreenElementScoreScreen::LoadNextLevel()
474 {
475 if (m_State == ScoreScreenState_Exiting)
476 {
477 return;
478 }
479
480 // Specify this
481 int nextLevelNum = m_NextLevelNumber;
482
483 m_pProcessMgr->AbortAllProcesses(true);
484 SAFE_DELETE(m_pProcessMgr);
485 IEventMgr::Get()->VAbortAllEvents();
486
487 IEventDataPtr pEvent(new EventData_Menu_LoadGame(nextLevelNum, false, 0));
488 IEventMgr::Get()->VQueueEvent(pEvent);
489 }
490
FinishedLoadingRowDelegate(IEventDataPtr pEventData)491 void ScreenElementScoreScreen::FinishedLoadingRowDelegate(IEventDataPtr pEventData)
492 {
493 if (m_State == ScoreScreenState_Finished)
494 {
495 return;
496 }
497
498 // Continue loading rows as long as its not empty
499 if (!m_ScoreRowList.empty())
500 {
501 ScoreRowDef row = m_ScoreRowList.front();
502
503 StrongProcessPtr pRowProcess(new SpawnScoreRowProcess(row));
504 m_pProcessMgr->AttachProcess(pRowProcess);
505
506 m_SpawnRowProcessList.push_back(pRowProcess);
507
508 m_ScoreRowList.erase(m_ScoreRowList.begin());
509 }
510
511 // No more rows, we can finish
512 if (m_ScoreRowList.empty())
513 {
514 m_State = ScoreScreenState_Finished;
515 }
516 }
517
ScoreScreenFinishedIntroDelegate(IEventDataPtr pEventData)518 void ScreenElementScoreScreen::ScoreScreenFinishedIntroDelegate(IEventDataPtr pEventData)
519 {
520 // Already loaded score screen ?
521 if (m_State == ScoreScreenState_SpawningScoreRows ||
522 m_State == ScoreScreenState_Finished)
523 {
524 return;
525 }
526
527 m_State = ScoreScreenState_SpawningScoreRows;
528
529 assert(m_pScoreBackgroundImage != nullptr);
530 m_pBackground = m_pScoreBackgroundImage;
531
532 // Destroy any spawned actors
533 for (auto actorIter : m_ActorMap)
534 {
535 IEventMgr::Get()->VQueueEvent(IEventDataPtr(new EventData_Destroy_Actor(actorIter.first)));
536 }
537
538 // Create score numbers of how many score points we gained in game and in level
539
540 //
541 // SYMBOL: GAME symbol
542 //
543 {
544 Point position(95, 465);
545 std::string symbolImagePath = "/STATES/BOOTY/IMAGES/SYMBOLS/GAME4.PID";
546
547 StrongActorPtr pOfSymbolImageActor = SpawnImageActor(
548 symbolImagePath,
549 position);
550 }
551
552 //
553 // NUMBERS: GAME total score
554 //
555 {
556 Point position(165, 465);
557
558 AddNumberImageActorsToList(
559 m_ScorePointsOnLevelStart,
560 m_ScorePointsOnLevelStart + m_ScorePointsCollectedInLevel,
561 position,
562 m_GameScoreNumbersList);
563 }
564
565 //
566 // SYMBOL: LEVEL symbol
567 //
568 {
569 Point position(425, 465);
570 std::string symbolImagePath = "/STATES/BOOTY/IMAGES/SYMBOLS/LEVEL5.PID";
571
572 StrongActorPtr pOfSymbolImageActor = SpawnImageActor(
573 symbolImagePath,
574 position);
575 }
576
577 //
578 // NUMBERS: LEVEL total score
579 //
580 {
581 Point position(495, 465);
582
583 AddNumberImageActorsToList(
584 0,
585 m_ScorePointsCollectedInLevel,
586 position,
587 m_LevelScoreNumbersList);
588 }
589
590 // Spawn first score row. When its loading is finished it will fire an event which we will catch
591
592 assert(!m_ScoreRowList.empty());
593 ScoreRowDef row = m_ScoreRowList[0];
594
595 StrongProcessPtr pRowProcess(new SpawnScoreRowProcess(row));
596 m_pProcessMgr->AttachProcess(pRowProcess);
597
598 m_ScoreRowList.erase(m_ScoreRowList.begin());
599 }
600
ScoreScreenLevelScoreAddedDelegate(IEventDataPtr pEventData)601 void ScreenElementScoreScreen::ScoreScreenLevelScoreAddedDelegate(IEventDataPtr pEventData)
602 {
603 shared_ptr<EventData_ScoreScreen_Level_Score_Added> pCastEventData =
604 static_pointer_cast<EventData_ScoreScreen_Level_Score_Added>(pEventData);
605
606 m_DisplayedGameScore += pCastEventData->GetAddedScore();
607 m_DisplayedLevelScore += pCastEventData->GetAddedScore();
608
609 // Update total game score
610 UpdateScoreImageNumbers(m_DisplayedGameScore, m_GameScoreNumbersList);
611
612 // Update level score
613 UpdateScoreImageNumbers(m_DisplayedLevelScore, m_LevelScoreNumbersList);
614 }
615
Initialize(TiXmlElement * pScoreScreenRootElem)616 bool ScreenElementScoreScreen::Initialize(TiXmlElement* pScoreScreenRootElem)
617 {
618 m_pProcessMgr = new ProcessMgr();
619 IEventMgr::Get()->VAbortAllEvents();
620
621 m_State = ScoreScreenState_Intro;
622
623 // Set correct palette
624 WapPal* pScoreScreenPalette = WAP_PalLoadFromData((char*)g_ScoreScreenPalette, 768);
625 assert(pScoreScreenPalette != NULL);
626 g_pApp->SetCurrentPalette(pScoreScreenPalette);
627
628 // Setup background sound
629 SoundInfo backgroundSound;
630 if (TiXmlElement* pBackgroundSoundElem = pScoreScreenRootElem->FirstChildElement("BackgroundSound"))
631 {
632 ParseValueFromXmlElem(&backgroundSound.soundToPlay, pBackgroundSoundElem->FirstChildElement("SoundPath"));
633 ParseValueFromXmlElem(&backgroundSound.soundVolume, pBackgroundSoundElem->FirstChildElement("Volume"));
634 ParseValueFromXmlElem(&backgroundSound.isMusic, pBackgroundSoundElem->FirstChildElement("IsMusic"));
635 }
636 assert(ParseValueFromXmlElem(&backgroundSound.soundToPlay, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.SoundPath"));
637 assert(ParseValueFromXmlElem(&backgroundSound.soundVolume, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.Volume"));
638 assert(ParseValueFromXmlElem(&backgroundSound.isMusic, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.IsMusic"));
639 bool isLooping = true;
640 ParseValueFromXmlElem(&isLooping, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.IsLooping");
641 backgroundSound.loops = isLooping ? -1 : 0;
642 assert(!backgroundSound.soundToPlay.empty());
643 IEventMgr::Get()->VQueueEvent(IEventDataPtr(new EventData_Request_Play_Sound(backgroundSound)));
644
645 // Setup intro background image
646 std::string initialBackgroundImagePath;
647 assert(ParseValueFromXmlElem(&initialBackgroundImagePath, pScoreScreenRootElem->FirstChildElement("InitialBackgroundScreen")));
648 m_pBackground = PcxResourceLoader::LoadAndReturnImage(initialBackgroundImagePath.c_str());
649
650 // Setup score screen background image
651 std::string scoreBackgroundImagePath;
652 assert(ParseValueFromXmlElem(&scoreBackgroundImagePath, pScoreScreenRootElem->FirstChildElement("ScoreBackgroundScreen")));
653 m_pScoreBackgroundImage = PcxResourceLoader::LoadAndReturnImage(scoreBackgroundImagePath.c_str());
654
655 if (TiXmlElement* pAcquiredPieceElem = pScoreScreenRootElem->FirstChildElement("AcquiredPiece"))
656 {
657 std::string acquiredPieceImagePath;
658 Point acquiredPiecePosition;
659 AnimationDef aniDef;
660 int delay;
661 std::string sound;
662
663 assert(ParseValueFromXmlElem(&acquiredPieceImagePath, pAcquiredPieceElem->FirstChildElement("ImagePath")));
664 assert(ParseValueFromXmlElem(&acquiredPiecePosition, pAcquiredPieceElem->FirstChildElement("Position"), "x", "y"));
665 assert(ParseValueFromXmlElem(&delay, pAcquiredPieceElem->FirstChildElement("Delay")));
666 assert(ParseValueFromXmlElem(&sound, pAcquiredPieceElem->FirstChildElement("SoundPath")));
667 if (TiXmlElement* pAnimElem = pAcquiredPieceElem->FirstChildElement("AnimationDef"))
668 {
669 assert(ParseValueFromXmlElem(&aniDef.hasAnimation, pAnimElem->FirstChildElement("HasAnimation")));
670 assert(ParseValueFromXmlElem(&aniDef.isCycleAnimation, pAnimElem->FirstChildElement("IsCycleAnimation")));
671 assert(ParseValueFromXmlElem(&aniDef.cycleAnimationDuration, pAnimElem->FirstChildElement("CycleDuration")));
672 }
673
674 StrongProcessPtr pShowAcquiredPieceImageProc(new ImageSpawnProcess(
675 acquiredPieceImagePath,
676 acquiredPiecePosition,
677 aniDef));
678 QueueDelayedProcess(pShowAcquiredPieceImageProc, delay);
679
680 SoundInfo soundInfo(sound);
681 StrongProcessPtr pAcquiredPieceSoundProc(new PlaySoundProcess(soundInfo));
682 QueueDelayedProcess(pAcquiredPieceSoundProc, delay);
683 }
684 else
685 {
686 //assert(false && "Acquired piece XML element is missing");
687 LOG_WARNING("Acquired piece element is not present !");
688 }
689
690 int clawFinishDialogTime = 0;
691 if (TiXmlElement* pClawCommentSound = pScoreScreenRootElem->FirstChildElement("ClawCommentSound"))
692 {
693 int delay;
694 std::string sound;
695
696 assert(ParseValueFromXmlElem(&delay, pClawCommentSound->FirstChildElement("Delay")));
697 assert(ParseValueFromXmlElem(&sound, pClawCommentSound->FirstChildElement("SoundPath")));
698
699 SoundInfo soundInfo(sound);
700 StrongProcessPtr pClawCommentSoundProc(new PlaySoundProcess(soundInfo));
701 QueueDelayedProcess(pClawCommentSoundProc, delay);
702
703 clawFinishDialogTime = delay + Util::GetSoundDurationMs(sound);
704 }
705 else
706 {
707 assert(false && "Claw comment sound XML element is missing");
708 }
709
710 assert(clawFinishDialogTime != 0);
711 //LOG("Claw will finish dialog in: " + ToStr(clawFinishDialogTime));
712
713 IEventDataPtr pFinishedIntroEvent(new EventData_ScoreScreen_Finished_Intro());
714 StrongProcessPtr pSpawnFinishedIntroProcess(new FireEventProcess(pFinishedIntroEvent, true));
715 QueueDelayedProcess(pSpawnFinishedIntroProcess, clawFinishDialogTime);
716
717 // Lets just assume that the background will take the whole screen
718 // From that we can calculate current scale (can't use predefined scale here)
719 m_OriginalScale = g_pApp->GetScale();
720 Point windowSize = g_pApp->GetWindowSize();
721 g_ScreenScale.Set(windowSize.x / m_pBackground->GetWidth(), windowSize.y / m_pBackground->GetHeight());
722 g_pApp->SetScale(g_ScreenScale);
723
724 // Load score rows
725 for (TiXmlElement* pScoreRowElem = pScoreScreenRootElem->FirstChildElement("ScoreRow");
726 pScoreRowElem != NULL;
727 pScoreRowElem = pScoreRowElem->NextSiblingElement("ScoreRow"))
728 {
729 ScoreRowDef scoreRowDef;
730
731 assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemImagePath,
732 pScoreRowElem->FirstChildElement("ScoreItemImagePath")));
733 assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemPickupSound,
734 pScoreRowElem->FirstChildElement("ScoreItemPickupSound")));
735 assert(ParseValueFromXmlElem(&scoreRowDef.rowStartPosition,
736 pScoreRowElem->FirstChildElement("RowStartPosition"), "x", "y"));
737 assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemPointsWorth,
738 pScoreRowElem->FirstChildElement("ScoreItemPointsWorth")));
739 assert(ParseValueFromXmlElem(&scoreRowDef.countOfPickedUpScoreItems,
740 pScoreRowElem->FirstChildElement("CountOfPickedUpScoreItems")));
741 assert(ParseValueFromXmlElem(&scoreRowDef.countOfMapScoreItems,
742 pScoreRowElem->FirstChildElement("CountOfTotalScoreItemsInLevel")));
743 assert(ParseValueFromXmlElem(&scoreRowDef.collectedScoreItemSpawnPosition,
744 pScoreRowElem->FirstChildElement("CollectedScoreItemSpawnPosition"), "x", "y"));
745
746 if (TiXmlElement* pScoreItemAnimElem = pScoreRowElem->FirstChildElement("ScoreItemAnimation"))
747 {
748 assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.hasAnimation,
749 pScoreItemAnimElem->FirstChildElement("HasAnimation")));
750
751 ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.isCycleAnimation,
752 pScoreItemAnimElem->FirstChildElement("IsCycleAnimation"));
753 ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.cycleAnimationDuration,
754 pScoreItemAnimElem->FirstChildElement("CycleDuration"));
755 ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.animationPath,
756 pScoreItemAnimElem->FirstChildElement("AnimationPath"));
757 }
758
759 if (TiXmlElement* pAlternativeImagesElem = pScoreRowElem->FirstChildElement("AlternativeImages"))
760 {
761 for (TiXmlElement* pAltImageElem = pAlternativeImagesElem->FirstChildElement("AlternativeImage");
762 pAltImageElem != NULL;
763 pAltImageElem = pAltImageElem->NextSiblingElement("AlternativeImage"))
764 {
765 std::string alternativeImage;
766 assert(ParseValueFromXmlElem(&alternativeImage, pAltImageElem));
767
768 scoreRowDef.alternativeImagesList.push_back(alternativeImage);
769 }
770 }
771
772 m_ScoreRowList.push_back(scoreRowDef);
773 }
774
775 // Info about finished level
776 assert(ParseValueFromXmlElem(&m_NextLevelNumber, pScoreScreenRootElem,
777 "FinishedLevelScreen.NextLevelNumber"));
778 assert(ParseValueFromXmlElem(&m_ScorePointsOnLevelStart, pScoreScreenRootElem,
779 "FinishedLevelScreen.ScorePointsOnLevelStart"));
780 assert(ParseValueFromXmlElem(&m_ScorePointsCollectedInLevel, pScoreScreenRootElem,
781 "FinishedLevelScreen.ScorePointsCollectedInLevel"));
782
783 return true;
784 };
785
QueueDelayedProcess(StrongProcessPtr pProcess,int delay)786 void ScreenElementScoreScreen::QueueDelayedProcess(StrongProcessPtr pProcess, int delay)
787 {
788 StrongProcessPtr pDelayProc = StrongProcessPtr(new DelayedProcess(delay));
789 pDelayProc->AttachChild(pProcess);
790 m_pProcessMgr->AttachProcess(pDelayProc);
791 }