1 // BlinkenSisters - Hunt for the Lost Pixels
2 // Bringing back the fun of the 80s
3 //
4 // (C) 2005-08 Rene Schickbauer, Wolfgang Dautermann
5 //
6 // See LICENSE for licensing information
7 //
8
9
10 #include "globals.h"
11 #include "engine.h"
12 #include "levelhandler.h"
13 #include "background.h"
14 #include "background2.h"
15 #include "drawprimitives.h"
16 #include "showtext.h"
17 #include "debug.h"
18 #include "tiles.h"
19 #include "playersprite.h"
20 #include "colission.h"
21 #include "showloading.h"
22 #include "gameengine.h"
23 #include "showpicture.h"
24 #include "joystick.h"
25 #ifdef ALLOW_ACTIONCAPTURE
26 #include "actioncapture.h"
27 #endif // ALLOW_ACTIONCAPTURE
28 #include "sound.h"
29 #include "fgobjects.h"
30 #include "bl_lua.h"
31 #include "fonthandler.h"
32 #include "showvideo.h"
33 #include "fginlay.h"
34 #include "bmfconvert.h"
35 #include "errorhandler.h"
36 #include "triggers.h"
37 #include "outputfilter.h"
38 #include "blending.h"
39 #include "bl_lua_objbindings.h"
40 #ifndef DISABLE_NETWORK
41 #include "blpstream.h"
42 #include "mcufstream.h"
43 #endif // DISABLE_NETWORK
44 #include "bsgui.h"
45 #include "fonthandler.h"
46 #include "bsscreen.h"
47
48 #include <math.h>
49 #include <string.h>
50
51 Uint32 fgXoffs = 0;
52 Uint32 fgYoffs = 0;
53 double fgXoffsOld = 0;
54 double fgYoffsOld = 0;
55 double fgXoffsTmp = 0;
56 double fgYoffsTmp = 0;
57
58 Uint32 spriterelx;
59 Uint32 spriterely;
60 PLAYERSPRITETYPE mtype = PLAYERSPRITE_NOMOVE;
61 double spritex, spritey, spritevx, spritevy;
62 Uint32 mcoltype;
63 bool isJumping;
64 bool gameRunning;
65 double blinkdir = BLINKSPEED;
66 double blinkbright = 100;
67 Uint32 foundPixels = 0;
68 char errorMessage[100];
69 Sint32 leftright = 0;
70 Sint32 updown = 0;
71 bool leftpressed = false;
72 bool rightpressed = false;
73 bool uppressed = false;
74 bool downpressed = false;
75 bool lockedBG;
76 bool hasGravity;
77 bool freeMovement;
78 bool touchFGObject;
79 bool firstLoop;
80 bool canPaintSpecialTiles;
81 bool allowedToExit;
82 bool displayPlayerCoords;
83 bool isEditMode;
84 bool isGodMode;
85 bool attracktModeRunning;
86 bool killPlayer;
87 bool turboMode;
88 bool turboKeyPressed;
89 bool isPauseMode = false;
90 bool hasScriptPhysics;
91 bool enableQuickDraw = false;
92 Uint32 BS_MyTick = 0;
93 Uint32 BS_MyLastTick = 0;
94
95 FILE* poscapfh = 0;
96 #ifdef ALLOW_POSITIONCAPTURE
97 Uint32 poscapcount;
98 #endif // ALLOW_POSITIONCAPTURE
99 bool isAttrackMode;
100 SDL_Color PLAYMECOLOR_ACTIVE = { 0xff, 0xff, 0xff, 0 };
101 SDL_Color TEXTINFO_COLOR = { 0xe0, 0xe0, 0xe0, 0 };
102 SDL_Color TEXTINFO_TIMEALERT = { 0xff, 0x00, 0x00, 0 };
initEngine(bool initForAttractMode)103 void initEngine(bool initForAttractMode)
104 {
105 lockedBG = false;
106 hasGravity = true;
107 freeMovement = false;
108 allowedToExit = false;
109 canPaintSpecialTiles = true;
110 leftpressed = false;
111 rightpressed = false;
112 uppressed = false;
113 downpressed = false;
114 turboMode = false;
115 turboKeyPressed = false;
116 hasScriptPhysics = false;
117
118 loadMonsterSprites();
119 initLevel(gamedata.player->level);
120 initMonsters();
121 #ifndef DISABLE_NETWORK
122 if (blpport != 0) {
123 initBLPFrames();
124 } ;
125 if (mcufport != 0) {
126 initMCUFFrames();
127 } ;
128 #endif // DISABLE_NETWORK
129
130 spritex = lhandle.respawn_x;
131 spritey = lhandle.respawn_y;
132 spritevx = 0;
133 spritevy = 0;
134 leftright = 0;
135 updown = 0;
136 isJumping = false;
137 gameRunning = true;
138 foundPixels = 0;
139 firstLoop = true;
140 hasEatenPixel = false;
141 resetFGInlay();
142 isAttrackMode = false;
143 displayPlayerCoords = false;
144 isEditMode = false;
145 isGodMode = false;
146 killPlayer = false;
147 poscapfh = 0;
148
149 #ifdef ALLOW_POSITIONCAPTURE
150 if(!initForAttractMode) {
151 char poscapname[100];
152 sprintf(poscapname, "poscap_level_%d.bin", gamedata.player->level);
153 poscapfh = fopen(configGetPath(poscapname), "wb");
154 if(!poscapfh) {
155 DIE(ERROR_FILE_WRITE, configGetPath(poscapname));
156 }
157 poscapcount = 0;
158 }
159 #endif // ALLOW_POSITIONCAPTURE
160
161 }
162
deInitEngine()163 void deInitEngine ()
164 {
165 #ifndef DISABLE_NETWORK
166 if (blpport != 0) {
167 deInitBLPFrames();
168 } ;
169 if (mcufport != 0) {
170 deInitMCUFFrames();
171 } ;
172 #endif // DISABLE_NETWORK
173 if(poscapfh != 0) {
174 fclose(poscapfh);
175 poscapfh = 0;
176 }
177 deInitLevel();
178 unloadMonsterSprites();
179
180 if(enableColor3D) {
181 BS_Set3DMode(COLOR3D_NONE);
182 }
183 }
184
185
engineFullPhysics()186 void engineFullPhysics() {
187 // Full Physics-Engine
188 if(!turboMode) {
189 gLastTick += 1000 / PHYSICSFPS;
190 } else {
191 gLastTick += 1000 / (PHYSICSFPS*4);
192 }
193
194 if(lhandle.leveltime > 0) {
195 if (!isEditMode) {
196 if(!turboMode) {
197 lhandle.remaintime -= 0.01;
198 } else {
199 lhandle.remaintime -= 0.04;
200 }
201 }
202 if(lhandle.remaintime <= 0) {
203 displaymessage(displaymessage_INFO, "Level timeout - play faster!!!", 800);
204 spritevx = 0;
205 spritevy = 0;
206 spritex = lhandle.respawn_x;
207 spritey = lhandle.respawn_y;
208 gamedata.player->lives--;
209 leftpressed = false;
210 rightpressed = false;
211 uppressed = false;
212 downpressed = false;
213 firstLoop = true;
214 hasEatenPixel = false;
215 hasGravity = true;
216 isGodMode = false;
217 killPlayer = false;
218 turboMode = false;
219 turboKeyPressed = false;
220 lhandle.remaintime = (double)lhandle.leveltime;
221 // it costs some score if kate looses a life
222 gamedata.player->score -= lhandle.timemalusifkatedies;
223 if (gamedata.player->score < 0) gamedata.player->score = 0 ; /* no negative score? why not? :-) */
224 // Reset sprite display to default starting position
225 resetSpriteGFX();
226
227
228 // OO-LUA LUA Livelost Callback
229 if(lhandle.luaCB[CB_PLAYER_LIVELOST].cbName[0] != 0) {
230 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_PLAYER_LIVELOST].cbName, "");
231 }
232 if(!showVideo("livelost.bmf", false, false)) {
233 soundPlayFX(FX_KILL_PLAYER);
234 showPicture("livelost.jpg", 2000);
235 }
236 #ifdef ALLOW_ACTIONCAPTURE
237 stopActionCapture();
238 #endif // ALLOW_ACTIONCAPTURE
239 gLastTick = BS_GetTicks();
240 }
241 }
242
243 // Blinking of pixels
244 blinkbright += blinkdir;
245 if(blinkbright < 10 || blinkbright > 250) {
246 blinkdir = 0 - blinkdir;
247 }
248 advanceFGObjAnim();
249
250 // Inlay message
251 calcFGInlay();
252
253 // Monsters
254 monsterPhysics((Uint32)spritex, (Uint32)spritey);
255 if(lhandle.hasScript) {
256 blLuaCall(lhandle.blLuaState, "scriptPhysics", "");
257 }
258
259 // OO-LUA LUA Physics Callback
260 if(lhandle.luaCB[CB_ENGINE_PHYSICS].cbName[0] != 0) {
261 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_ENGINE_PHYSICS].cbName, "");
262 }
263
264 if(lhandle.hasScript || lhandle.hasOOScript) {
265 handleTriggers();
266 }
267
268 if(lhandle.hasOOScript) {
269 handlePlayerFGObjCallbacks();
270 }
271
272 // Left/Right movement with smooth acceleration/braking
273
274 if(leftright > 0) {
275 spritevx += SPRITE_ACCEL;
276 } else if(leftright < 0) {
277 spritevx -= SPRITE_ACCEL;
278 } else {
279 if(spritevx > SPRITE_ACCEL) {
280 spritevx -= SPRITE_ACCEL;
281 } else if(spritevx < -SPRITE_ACCEL) {
282 spritevx += SPRITE_ACCEL;
283 } else {
284 spritevx = 0;
285 }
286 }
287
288 if(freeMovement) {
289 if(updown > 0) {
290 spritevy += SPRITE_ACCEL;
291 } else if(updown < 0) {
292 spritevy -= SPRITE_ACCEL;
293 } else {
294 if(spritevy > SPRITE_ACCEL) {
295 spritevy -= SPRITE_ACCEL;
296 } else if(spritevy < -SPRITE_ACCEL) {
297 spritevy += SPRITE_ACCEL;
298 } else {
299 spritevy = 0;
300 }
301 }
302 }
303
304
305 // Gravity
306 if(hasGravity && !freeMovement) {
307 spritevy += SPRITE_GRAVITY;
308 }
309
310 // Limit speed
311 if(spritevx > SPRITE_MAXSPEED) {
312 spritevx = SPRITE_MAXSPEED;
313 } else if(spritevx < -SPRITE_MAXSPEED) {
314 spritevx = -SPRITE_MAXSPEED;
315 }
316 spritex += spritevx;
317
318 if(spritevy > SPRITE_MAXSPEED) {
319 spritevy = SPRITE_MAXSPEED;
320 } else if(spritevy < -SPRITE_MAXSPEED) {
321 spritevy = -SPRITE_MAXSPEED;
322 }
323
324 spritey += spritevy;
325
326 // Limit movement to stay within game-area
327 if(spritex > (lhandle.width - 32)) {
328 spritevx = 0;
329 spritex = lhandle.width - 32;
330 } else if(spritex < 0) {
331 spritevx = 0;
332 spritex = 0;
333 }
334
335
336 if(spritey > (lhandle.height - 32)) {
337 spritevy = 0;
338 spritey = lhandle.height - 32;
339 } else if(spritey < 0) {
340 spritevy = 0;
341 spritey = 0;
342 }
343
344
345 // Decide on playersprite movement/gfx selection
346 mtype = PLAYERSPRITE_NOMOVE;
347
348 if(leftright > 0) {
349 if(updown > 0) {
350 mtype = PLAYERSPRITE_RIGHTDOWN;
351 } else if(updown < 0) {
352 mtype = PLAYERSPRITE_RIGHTUP;
353 } else {
354 mtype = PLAYERSPRITE_RIGHT;
355 }
356 } else if(leftright < 0) {
357 if(updown > 0) {
358 mtype = PLAYERSPRITE_LEFTDOWN;
359 } else if(updown < 0) {
360 mtype = PLAYERSPRITE_LEFTUP;
361 } else {
362 mtype = PLAYERSPRITE_LEFT;
363 }
364 } else {
365 if(updown > 0) {
366 mtype = PLAYERSPRITE_DOWN;
367 } else if(updown < 0) {
368 mtype = PLAYERSPRITE_UP;
369 } else {
370 mtype = PLAYERSPRITE_NOMOVE;
371 }
372 }
373
374 if(isAttrackMode) {
375 spritex = (double)bmfReadInt(poscapfh);
376 spritey = (double)bmfReadInt(poscapfh);
377 mtype = (PLAYERSPRITETYPE)bmfReadInt(poscapfh);
378 if(spritex == 0 && spritey == 0) {
379 fclose(poscapfh);
380 poscapfh = 0;
381 gamedata.player->lives = 0;
382 gameRunning = false;
383 return;
384 }
385 }
386
387 #ifdef ALLOW_POSITIONCAPTURE
388 if(!isAttrackMode && poscapfh) {
389 bmfWriteInt(poscapfh, (Uint32)spritex);
390 bmfWriteInt(poscapfh, (Uint32)spritey);
391 bmfWriteInt(poscapfh, (Uint32)mtype);
392 poscapcount++;
393 if(poscapcount == 1700) {
394 bmfWriteInt(poscapfh, (Uint32)0);
395 bmfWriteInt(poscapfh, (Uint32)0);
396 bmfWriteInt(poscapfh, (Uint32)0);
397 fclose(poscapfh);
398 poscapfh = 0;
399 }
400 }
401 #endif // ALLOW_POSITIONCAPTURE
402
403 updateSpriteGFX(mtype);
404
405 handlePlayerTilesColission();
406 handlePlayerFGColission();
407
408 mcoltype = getPlayerMonsterColission();
409 if(mcoltype & COL_UP || mcoltype & COL_LEFT || mcoltype & COL_RIGHT || getPlayerFGKillColission() || killPlayer) {
410 if (!isGodMode) {
411 spritevx = 0;
412 spritevy = 0;
413 spritex = lhandle.respawn_x;
414 spritey = lhandle.respawn_y;
415 gamedata.player->lives--;
416 leftpressed = false;
417 rightpressed = false;
418 uppressed = false;
419 downpressed = false;
420 firstLoop = true;
421 hasEatenPixel = false;
422 hasGravity = true;
423 freeMovement = isEditMode;
424 isGodMode = false;
425 killPlayer = false;
426 turboMode = false;
427 turboKeyPressed = false;
428 lhandle.remaintime = (double)lhandle.leveltime;
429 //it costs some score if kate looses a life
430 gamedata.player->score -= lhandle.timemalusifkatedies;
431 if (gamedata.player->score < 0) gamedata.player->score = 0 ; /* no negative score? why not? :-) */
432 // Reset sprite display to default starting position
433 resetSpriteGFX();
434
435 // OO-LUA LUA Livelost Callback
436 if(lhandle.luaCB[CB_PLAYER_LIVELOST].cbName[0] != 0) {
437 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_PLAYER_LIVELOST].cbName, "");
438 }
439 if(!showVideo("livelost.bmf", false, false)) {
440 soundPlayFX(FX_KILL_PLAYER);
441 showPicture("livelost.jpg", 2000);
442 }
443 #ifdef ALLOW_ACTIONCAPTURE
444 stopActionCapture();
445 #endif // ALLOW_ACTIONCAPTURE
446 gLastTick = BS_GetTicks();
447 return;
448 }
449 }
450
451 touchFGObject = false;
452
453 // Check if the player has enough pixels to exit
454 if(foundPixels == lhandle.numPixels) {
455 allowedToExit = true;
456 }
457
458 bool colWithExit = handlePixelCollission();
459 if(colWithExit) {
460 if(allowedToExit) {
461 printf("LEVEL FINISHED\n");
462 gameRunning = false;
463 } else {
464 sprintf(errorMessage, "Level not finished!");
465 }
466 }
467
468
469 // Calculate relative positions of sprite, tiles and background
470 spriterelx = SCR_WIDTH / 2;
471 spriterely = SCR_HEIGHT / 2;
472
473 if(spritex < spriterelx) {
474 fgXoffs = 0;
475 spriterelx = (Uint32)spritex;
476 } else if(spritex > (lhandle.width - spriterelx)) {
477 spriterelx = SCR_WIDTH - (lhandle.width - (Uint32)spritex);
478 fgXoffs = lhandle.width - SCR_WIDTH;
479 } else {
480 fgXoffs = (Uint32)spritex - spriterelx;
481 }
482
483 if(spritey < spriterely) {
484 fgYoffs = 0;
485 spriterely = (Uint32)spritey;
486 } else if(spritey > (lhandle.height - spriterely)) {
487 spriterely = SCR_HEIGHT - (lhandle.height - (Uint32)spritey);
488 fgYoffs = lhandle.height - SCR_HEIGHT;
489 } else {
490 fgYoffs = (Uint32)spritey - spriterely;
491 }
492
493
494 #ifdef ALLOW_SMOOTHPANNING
495 // --- Start of smooth panning feature
496 if(firstLoop) {
497 firstLoop = false;
498 fgXoffsOld = (double)fgXoffs;
499 fgYoffsOld = (double)fgYoffs;
500 }
501
502 fgXoffsTmp = fgXoffsOld - (fgXoffsOld - (double)fgXoffs) / SMOOTHPANNING_FACTOR;
503 if(fgXoffsTmp < 0.0) {
504 fgXoffsTmp = 0.0;
505 }
506
507 fgYoffsTmp = fgYoffsOld - (fgYoffsOld - (double)fgYoffs) / SMOOTHPANNING_FACTOR;
508 if(fgYoffsTmp < 0.0) {
509 fgYoffsTmp = 0.0;
510 }
511
512 //spriterelx = spriterelx + (Uint32)(fgXoffsTmp) - fgXoffs;
513 //spriterely = spriterely + ((Uint32)(fgYoffsTmp) - fgYoffs);
514
515 fgXoffsOld = fgXoffsTmp;
516 fgYoffsOld = fgYoffsTmp;
517
518 Sint32 tmpSX = (Sint32)spritex - (Sint32)fgXoffsTmp;
519 if(tmpSX < 0) {
520 tmpSX = 0;
521 } else if(tmpSX > SCR_WIDTH - TILESIZE) {
522 tmpSX = SCR_WIDTH - TILESIZE;
523 }
524 spriterelx = tmpSX;
525
526 Sint32 tmpSY = (Sint32)spritey - (Sint32)fgYoffsTmp;
527 if(tmpSY < 0) {
528 tmpSY = 0;
529 } else if(tmpSY > SCR_HEIGHT - TILESIZE) {
530 tmpSY = SCR_HEIGHT - TILESIZE;
531 }
532 spriterely = tmpSY;
533
534 //printf("X: %d Y: %d\n", spriterelx, spriterely);
535
536
537 fgXoffs = (Uint32)fgXoffsTmp;
538 fgYoffs = (Uint32)fgYoffsTmp;
539
540 // --- End of smooth panning feature
541 #endif // ALLOW_SMOOTHPANNING
542
543
544 }
545
engineMinimalPhysics()546 void engineMinimalPhysics() {
547 // Minimal Physics-Engine
548 if(!turboMode) {
549 gLastTick += 1000 / PHYSICSFPS;
550 } else {
551 gLastTick += 1000 / (PHYSICSFPS*4);
552 }
553
554 advanceFGObjAnim();
555
556 // Inlay message
557 calcFGInlay();
558
559 if(lhandle.hasScript) {
560 blLuaCall(lhandle.blLuaState, "scriptPhysics", "");
561 }
562
563 // OO-LUA LUA Physics Callback
564 if(lhandle.luaCB[CB_ENGINE_PHYSICS].cbName[0] != 0) {
565 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_ENGINE_PHYSICS].cbName, "");
566 }
567
568 if(lhandle.hasScript || lhandle.hasOOScript) {
569 handleTriggers();
570 }
571
572 if(lhandle.hasOOScript) {
573 handlePlayerFGObjCallbacks();
574 }
575
576
577
578 // Decide on playersprite movement/gfx selection
579 /*
580 mtype = PLAYERSPRITE_NOMOVE;
581
582 if(leftright > 0) {
583 if(updown > 0) {
584 mtype = PLAYERSPRITE_RIGHTDOWN;
585 } else if(updown < 0) {
586 mtype = PLAYERSPRITE_RIGHTUP;
587 } else {
588 mtype = PLAYERSPRITE_RIGHT;
589 }
590 } else if(leftright < 0) {
591 if(updown > 0) {
592 mtype = PLAYERSPRITE_LEFTDOWN;
593 } else if(updown < 0) {
594 mtype = PLAYERSPRITE_LEFTUP;
595 } else {
596 mtype = PLAYERSPRITE_LEFT;
597 }
598 } else {
599 if(updown > 0) {
600 mtype = PLAYERSPRITE_DOWN;
601 } else if(updown < 0) {
602 mtype = PLAYERSPRITE_UP;
603 } else {
604 mtype = PLAYERSPRITE_NOMOVE;
605 }
606 }
607 */
608
609
610
611
612 }
613
renderEngine()614 void renderEngine() {
615
616 errorMessage[0] = 0;
617
618 // Ask SDL for the time in milliseconds
619 Uint32 tick = BS_GetTicks();
620
621 // Delay a bit if we're too fast
622 if(!isPauseMode) {
623 while (tick <= gLastTick) {
624 SDL_Delay(1);
625 tick = BS_GetTicks();
626 }
627 }
628
629 while (gameRunning && gLastTick < tick) {
630 if(!hasScriptPhysics) {
631 engineFullPhysics();
632 } else {
633 engineMinimalPhysics();
634 }
635 }
636
637
638
639 // We are painting; allow LUA paint calls
640 allowLUAPaint = true;
641
642
643
644
645 if(enableColor3D) {
646 BS_Set3DMode(COLOR3D_LEFT);
647 engineDoRender(COLOR3D_LEFT);
648 BS_Set3DMode(COLOR3D_RIGHT);
649 engineDoRender(COLOR3D_RIGHT);
650 // BS_Set3DMode(COLOR3D_NONE); // Don't need this?
651 } else {
652 engineDoRender(COLOR3D_NONE);
653 }
654
655
656 allowLUAPaint = false;
657
658
659 // Tell SDL to update the whole screen
660 BS_Flip(gScreen);
661
662 #ifdef ALLOW_ACTIONCAPTURE
663 renderActionCapture(spriterelx, spriterely);
664 #endif // ALLOW_ACTIONCAPTURE
665
666 #ifndef DISABLE_NETWORK
667 if (blpport != 0) {
668 sendBLPFrame();
669 } ;
670 if (mcufport != 0) {
671 sendMCUFFrame();
672 } ;
673 #endif // DISABLE_NETWORK
674
675
676 }
677
engineDoRender(COLOR3D mode3D)678 void engineDoRender(COLOR3D mode3D)
679 {
680
681 Uint32 bg2offs, bgoffs, fgoffs, txtoffs;
682
683 if(mode3D == COLOR3D_NONE) {
684 bg2offs = bgoffs = fgoffs = txtoffs = 0;
685 } else if(mode3D == COLOR3D_LEFT) {
686 bg2offs = bgoffs = 0;
687 fgoffs = 5;
688 txtoffs = 2;
689 } else {
690 bg2offs = 20;
691 bgoffs = 10;
692 fgoffs = txtoffs = 0;
693 }
694
695
696 if(!lockedBG) {
697 if(!lhandle.hasBG2) {
698 drawBackground((fgXoffs / 2) + bgoffs, fgYoffs / 2);
699 } else {
700 drawBackground((fgXoffs / 4) + bg2offs, fgYoffs / 4);
701 drawBackground2((fgXoffs / 2) + bgoffs, fgYoffs / 2);
702 }
703 } else {
704 drawBackground(fgXoffs + bgoffs, fgYoffs);
705 }
706
707 // LUA Painting - STAGE 1
708 if(lhandle.luaCB[CB_RENDER_STAGE_1].cbName[0] != 0) {
709 // Lock screen if needed
710 if (SDL_MUSTLOCK(gScreen))
711 if (SDL_LockSurface(gScreen) < 0)
712 return;
713 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_RENDER_STAGE_1].cbName, "");
714 // Unlock screen if needed
715 if (SDL_MUSTLOCK(gScreen))
716 SDL_UnlockSurface(gScreen);
717 }
718
719 paintFGObjs(fgXoffs, fgYoffs, false);
720 paintLevelTiles(fgXoffs, fgYoffs);
721
722 // LUA Painting - STAGE 2
723 if(lhandle.luaCB[CB_RENDER_STAGE_2].cbName[0] != 0) {
724 // Lock screen if needed
725 if (SDL_MUSTLOCK(gScreen))
726 if (SDL_LockSurface(gScreen) < 0)
727 return;
728 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_RENDER_STAGE_2].cbName, "");
729 // Unlock screen if needed
730 if (SDL_MUSTLOCK(gScreen))
731 SDL_UnlockSurface(gScreen);
732 }
733
734 if(!hasScriptPhysics) {
735 // Paint pixels only if it's internal engine physics
736 paintLevelPixels(fgXoffs, fgYoffs, (Uint32)blinkbright);
737 }
738
739 // LUA Painting - STAGE 3
740 if(lhandle.luaCB[CB_RENDER_STAGE_3].cbName[0] != 0) {
741 // Lock screen if needed
742 if (SDL_MUSTLOCK(gScreen))
743 if (SDL_LockSurface(gScreen) < 0)
744 return;
745 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_RENDER_STAGE_3].cbName, "");
746 // Unlock screen if needed
747 if (SDL_MUSTLOCK(gScreen))
748 SDL_UnlockSurface(gScreen);
749 }
750
751 if(!hasScriptPhysics) {
752 // Paint sprites only if it's internal engine physics
753 showMonsterSprites(fgXoffs, fgYoffs);
754 showSprite(spriterelx, spriterely);
755 }
756
757 // LUA Painting - STAGE 4
758 if(lhandle.luaCB[CB_RENDER_STAGE_4].cbName[0] != 0) {
759 // Lock screen if needed
760 if (SDL_MUSTLOCK(gScreen))
761 if (SDL_LockSurface(gScreen) < 0)
762 return;
763 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_RENDER_STAGE_4].cbName, "");
764 // Unlock screen if needed
765 if (SDL_MUSTLOCK(gScreen))
766 SDL_UnlockSurface(gScreen);
767 }
768
769 // LUA Painting - STAGE 5
770 if(lhandle.luaCB[CB_RENDER_STAGE_5].cbName[0] != 0) {
771 // Lock screen if needed
772 if (SDL_MUSTLOCK(gScreen))
773 if (SDL_LockSurface(gScreen) < 0)
774 return;
775 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_RENDER_STAGE_5].cbName, "");
776 // Unlock screen if needed
777 if (SDL_MUSTLOCK(gScreen))
778 SDL_UnlockSurface(gScreen);
779 }
780
781
782 // HUD ("Head-up-display")
783 // LUA Painting - STAGE HUD
784 if(lhandle.luaCB[CB_RENDER_STAGE_HUD].cbName[0] != 0) {
785 // Lock screen if needed
786 if (SDL_MUSTLOCK(gScreen))
787 if (SDL_LockSurface(gScreen) < 0)
788 return;
789 blLuaCall(lhandle.blOOLuaState, lhandle.luaCB[CB_RENDER_STAGE_HUD].cbName, "");
790 // Unlock if needed
791 if (SDL_MUSTLOCK(gScreen))
792 SDL_UnlockSurface(gScreen);
793 } else {
794 if(!enableQuickDraw) {
795 if(!turboMode) {
796 if(lhandle.leveltime <= 0) {
797 blend_darkenRect(3, 3, SCR_WIDTH-6, 24, 0x00606060);
798 } else {
799 blend_darkenRect(3, 3, SCR_WIDTH-6, 48, 0x00606060);
800 }
801 } else {
802 if(lhandle.leveltime <= 0) {
803 blend_darkenRect(3, 3, SCR_WIDTH-6, 24, 0x00808080);
804 blend_brightenRect(3, 3, SCR_WIDTH-6, 24, 0x00500000);
805 } else {
806 blend_darkenRect(3, 3, SCR_WIDTH-6, 48, 0x00808080);
807 blend_brightenRect(3, 3, SCR_WIDTH-6, 48, 0x00500000);
808 }
809 }
810 }
811 }
812
813
814 char printString[100];
815 sprintf(printString, "Pixels: %u (%u)", foundPixels, lhandle.numPixels);
816 renderFontHandlerText(20 + txtoffs, 2, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
817
818 sprintf(printString, "Lives: %u", gamedata.player->lives);
819 renderFontHandlerText(190 + txtoffs, 2, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
820
821 sprintf(printString, "Level: %u", gamedata.player->level);
822 renderFontHandlerText(310 + txtoffs, 2, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
823
824 sprintf(printString, "Score: %u", gamedata.player->score);
825 renderFontHandlerText(440 + txtoffs, 2, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
826
827 if(enteringCheat) {
828 if(!enableQuickDraw) {
829 blend_darkenRect(5, SCR_HEIGHT-35, SCR_WIDTH-10, 30, 0x00808080);
830 blend_brightenRect(5, SCR_HEIGHT-35, SCR_WIDTH-10, 30, 0x00500000);
831 }
832 if (SDL_GetTicks() % 200 < 100) { // blinking cursor
833 sprintf(printString, "CHEAT: %s_", cheatCode);
834 } else {
835 sprintf(printString, "CHEAT: %s ", cheatCode);
836 } ;
837 renderFontHandlerText(20 + txtoffs, SCR_HEIGHT-30, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
838 }
839
840 if(lhandle.leveltime > 0) {
841 sprintf(printString, "Rem. Time: %d", (Uint32)lhandle.remaintime);
842 if(lhandle.remaintime <= 10) { /* red font, if the leveltime <= 10 sec */
843 renderFontHandlerText(20 + txtoffs, 25, printString, TEXTINFO_TIMEALERT, false, false, FONT_textfont_20);
844 } else {
845 renderFontHandlerText(20 + txtoffs, 25, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20) ;
846 } ;
847 Uint32 timebar = 0;
848 if(lhandle.remaintime <= lhandle.leveltime) {
849 timebar = (Uint32)(((lhandle.leveltime - lhandle.remaintime) * 300.0) / lhandle.leveltime);
850 drawrect(200, 35, timebar, 7, 0xff0000);
851 drawrect(200 + timebar, 35, 300-timebar, 7, 0x00ff00);
852 } else {
853 drawrect(200, 35, 300, 7, 0x00ff00);
854 drawrect(201, 36, 298, 5, (Uint32)(blinkbright + blinkbright * 256 + blinkbright * 65536));
855 SDL_Color blibri1 = {(Uint8)blinkbright, (Uint8)blinkbright, (Uint8)blinkbright, 0};
856 SDL_Color blibri2 = {(Uint8)(255 - blinkbright), (Uint8)(255 - blinkbright), (Uint8)(255 - blinkbright), (Uint8)blinkbright};
857 renderFontHandlerText(520 + txtoffs, 27, "Bonus", blibri1, false, false, FONT_textfont_8);
858 renderFontHandlerText(530 + txtoffs, 33, "Time", blibri2, false, false, FONT_textfont_8) ;
859 }
860
861 }
862
863 renderFontHandlerText(20 + txtoffs, 45, errorMessage, TEXTINFO_TIMEALERT, true, true, FONT_menufont_20);
864
865 paintFGObjs(fgXoffs + fgoffs, fgYoffs, true);
866
867
868
869 #ifdef ALLOW_POSITIONCAPTURE
870 if(!isAttrackMode && poscapfh) {
871 renderFontHandlerText(20 + txtoffs, 60, "Position Capture (smile, please)", TEXTINFO_COLOR, false, false, FONT_textfont_20);
872 }
873 #endif // ALLOW_POSITIONCAPTURE
874
875
876 #ifdef DISPLAY_PLAYERCOORDS
877 if(displayPlayerCoords && !enteringCheat) {
878 if(!enableQuickDraw) {
879 blend_darkenRect(5 + txtoffs, 445, SCR_WIDTH-10, 30, 0x00808080);
880 blend_brightenRect(5 + txtoffs, 445, SCR_WIDTH-10, 30, 0x00500000);
881 }
882 sprintf(printString, "X: %u", (Uint32)spritex);
883 renderFontHandlerText(20 + txtoffs, 450, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
884 sprintf(printString, "Y: %u", (Uint32)spritey);
885 renderFontHandlerText(120 + txtoffs, 450, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
886 sprintf(printString, "X: %u", (Uint32)((spritex/TILESIZE)+1));
887 renderFontHandlerText(330 + txtoffs, 450, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
888 sprintf(printString, "Y: %u", (Uint32)((spritey/TILESIZE)+1));
889 renderFontHandlerText(420 + txtoffs, 450, printString, TEXTINFO_COLOR, false, false, FONT_textfont_20);
890 }
891 #endif // DISPLAY_PLAYERCOORDS
892
893
894 if(isAttrackMode) {
895 // These texts are handled like fgobjects in Color3D
896 if((BS_GetTicks() % 10000) < 5000) {
897 renderFontHandlerText(50 + fgoffs, 200, "PLAY ME!", PLAYMECOLOR_ACTIVE, true, true, FONT_menufont_50);
898 } else {
899 renderFontHandlerText(50 + fgoffs, 200, "SPIEL MICH!", PLAYMECOLOR_ACTIVE, true, true, FONT_menufont_50);
900 }
901 }
902 #ifdef SHOW_INLAY
903 if(!enteringCheat && !displayPlayerCoords) {
904 renderFGInlay();
905 }
906 #endif // SHOW_INLAY
907
908
909 if(isPauseMode) {
910 // Handle text like fgobj in Color3D
911 if(!enableQuickDraw) {
912 blend_darkenRect(10, 10, SCR_WIDTH-20, SCR_HEIGHT-20, 0x00808080);
913 }
914 renderFontHandlerText(50 + fgoffs, 200, "PAUSE MODE", PLAYMECOLOR_ACTIVE, true, true, FONT_menufont_50);
915 SDL_Delay(100);
916 } else if(lhandle.leveltime > 0 && lhandle.remaintime <= 10) {
917 // Handle text like fgobj in Color3D
918 if((int)lhandle.remaintime % 2) {
919 renderFontHandlerText(50 + fgoffs, 200, "! HURRY UP !", TEXTINFO_TIMEALERT, true, true, FONT_menufont_50);
920 }
921 }
922
923 #ifdef SHOWFRAMERATE
924 if(mode3D == COLOR3D_RIGHT) {
925 displayFPSCounter(true);
926 } else {
927 displayFPSCounter();
928 }
929 #endif // SHOWFRAMERATE
930
931 applyOutputFilter();
932
933 }
934
935 char cheatCode[MAX_STRING_LENGTH];
936 bool enteringCheat = false;
displayEngine(const char * attrackModeFile)937 void displayEngine(const char* attrackModeFile)
938 {
939
940 leftpressed = false;
941 rightpressed = false;
942 SDL_Event event;
943
944 // Special for attrack mode
945 if(attrackModeFile) {
946 gLastTick = BS_GetTicks();
947 isAttrackMode = true;
948 poscapfh = fopen(configGetPath(attrackModeFile), "rb");
949 if(!poscapfh) {
950 DIE(ERROR_FILE_READ, configGetPath(attrackModeFile));
951 }
952
953 // Catch all user input. Poll for events, and handle the ones we care about.
954 while(gameRunning) {
955 while(SDL_PollEvent(&event)) {
956 switch (event.type)
957 {
958 case SDL_KEYUP:
959 gameRunning = false;
960 attracktModeRunning = false;
961 break;
962 case SDL_QUIT:
963 exit(0);
964 }
965 }
966 Uint32 joymove = getJoystickMoves();
967 if(joymove & JOYSTICK_JUMP || joymove & JOYSTICK_ACTION) {
968 gameRunning = false;
969 attracktModeRunning = false;
970 }
971 renderEngine();
972 }
973 return;
974 }
975
976
977 Uint32 cheatTick = 0;
978 gLastTick = BS_GetTicks();
979
980 while (gameRunning && gamedata.player->lives > 0)
981 {
982 Uint32 ticks = BS_GetTicks();
983 // Render stuff
984
985 // Get Joystick moves
986 Uint32 joymove = getJoystickMoves();
987 if(!freeMovement) {
988 if((joymove & JOYSTICK_JUMP) && !isJumping && (touchFGObject || (spritevy < SPRITE_FALLSILENTTHRESHOLD))) {
989 isJumping = true;
990 spritevy = SPRITE_JUMPSPEED;
991 }
992 }
993
994 // Calculate reftright offset
995 if((leftpressed && !rightpressed) || (joymove & JOYSTICK_LEFT)){
996 leftright = -1;
997 } else if((!leftpressed && rightpressed) || (joymove & JOYSTICK_RIGHT)){
998 leftright = 1;
999 } else {
1000 leftright = 0;
1001 }
1002
1003 if(freeMovement) {
1004 // Calculate updown offset
1005 if((uppressed && !downpressed) || (joymove & JOYSTICK_UP)){
1006 updown = -1;
1007 } else if((!uppressed && downpressed) || (joymove & JOYSTICK_DOWN)){
1008 updown = 1;
1009 } else {
1010 updown = 0;
1011 }
1012 isJumping = 0;
1013 } else {
1014 uppressed = false;
1015 downpressed = false;
1016 updown = 0;
1017 }
1018
1019 if(joymove & JOYSTICK_ACTION) {
1020 doFGPlayerAction((Uint32)spritex, (Uint32)spritey);
1021 }
1022
1023 if(joymove & JOYSTICK_PAUSE) {
1024 isPauseMode = !isPauseMode;
1025 }
1026
1027 renderEngine();
1028 if(ticks > cheatTick) {
1029 cheatTick = BS_GetTicks() + CHEATTIMEOUT;
1030 cheatCode[0] = 0;
1031 enteringCheat = false;
1032 }
1033
1034 // Poll for events, and handle the ones we care about.
1035 while (SDL_PollEvent(&event) && gameRunning)
1036 {
1037 switch (event.type)
1038 {
1039 case SDL_KEYDOWN:
1040 if (event.key.keysym.sym == SDLK_LEFT ||
1041 event.key.keysym.sym == SDLK_KP4) {
1042 //leftright -= 1;
1043 leftpressed = true;
1044 } else if (event.key.keysym.sym == SDLK_RIGHT ||
1045 event.key.keysym.sym == SDLK_KP6) {
1046 //leftright += 1;
1047 rightpressed = true;
1048 } else if (event.key.keysym.sym == SDLK_UP ||
1049 event.key.keysym.sym == SDLK_KP8) {
1050 if(!freeMovement && event.key.keysym.sym != SDLK_KP8) {
1051 if(touchFGObject || (!isJumping && spritevy < SPRITE_FALLSILENTTHRESHOLD)) {
1052 isJumping = true;
1053 spritevy = SPRITE_JUMPSPEED;
1054 }
1055 } else {
1056 uppressed = true;
1057 }
1058 } else if (event.key.keysym.sym == SDLK_KP1) {
1059 if(!freeMovement) {
1060 if(touchFGObject || (!isJumping && spritevy < SPRITE_FALLSILENTTHRESHOLD)) {
1061 isJumping = true;
1062 spritevy = SPRITE_JUMPSPEED;
1063 }
1064 }
1065
1066 } else if (event.key.keysym.sym == SDLK_DOWN ||
1067 event.key.keysym.sym == SDLK_KP2) {
1068 if(freeMovement) {
1069 downpressed = true;
1070 }
1071 } else if (event.key.keysym.sym == SDLK_PLUS ||
1072 event.key.keysym.sym == SDLK_RIGHTBRACKET) {
1073 turboKeyPressed = true;
1074 }
1075
1076
1077 break;
1078 case SDL_KEYUP:
1079 //printf("Key pressed: %d\n", event.key.keysym.sym);
1080 // If escape is pressed, return (and thus, quit)
1081 if (event.key.keysym.sym == SDLK_LEFT ||
1082 event.key.keysym.sym == SDLK_KP4) {
1083 //leftright += 1;
1084 leftpressed = false;
1085 } else if (event.key.keysym.sym == SDLK_RIGHT ||
1086 event.key.keysym.sym == SDLK_KP6) {
1087 rightpressed = false;
1088 //leftright -= 1;
1089 } else if (event.key.keysym.sym == SDLK_UP ||
1090 event.key.keysym.sym == SDLK_KP8) {
1091 if(freeMovement || event.key.keysym.sym == SDLK_KP8) {
1092 uppressed = false;
1093 }
1094 } else if (event.key.keysym.sym == SDLK_DOWN ||
1095 event.key.keysym.sym == SDLK_KP2) {
1096 if(freeMovement) {
1097 downpressed = false;
1098 }
1099 } else if (event.key.keysym.sym == SDLK_PLUS ||
1100 event.key.keysym.sym == SDLK_RIGHTBRACKET) {
1101 turboKeyPressed = false;
1102 } else if (enteringCheat == false && event.key.keysym.sym == SDLK_RETURN) {
1103 if(lhandle.musicPlaying == true) {
1104 lhandle.musicPlaying = false;
1105 soundStopMusic();
1106 } else {
1107 lhandle.musicPlaying = true;
1108 soundStartMusic(lhandle.sndfile);
1109 }
1110 // Handle the BOSS-Key (ESC) - fast EXIT.
1111 #ifdef ALLOW_BOSSKEY
1112 } else if (event.key.keysym.sym == SDLK_ESCAPE) {
1113 displaymessage(displaymessage_INFO, "Boss-key (ESC) hit - fast exit", 800);
1114 exit(0);
1115 #endif // ALLOW_BOSSKEY
1116 #ifdef ENABLE_FULLSCREEN
1117 } else if ((event.key.keysym.sym == SDLK_f) && (enteringCheat == false)) {
1118 /* Switching between fullscreen and
1119 * windowing not allowed, if we are entering a cheatcode now
1120 * (otherwise a cheatcode may not contain the character 'f' */
1121 isFullscreen = !isFullscreen;
1122 if(isFullscreen) {
1123 gScreen = BS_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 32, SDL_SWSURFACE | SDL_FULLSCREEN);
1124 } else {
1125 gScreen = BS_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 32, SDL_SWSURFACE);
1126 }
1127 #endif // ENABLE_FULLSCREEN
1128 #ifdef ALLOW_ACTIONCAPTURE
1129 } else if (event.key.keysym.sym == SDLK_y) {
1130 startActionCapture();
1131 } else if (event.key.keysym.sym == SDLK_x) {
1132 stopActionCapture();
1133 #endif // ALLOW_ACTIONCAPTURE
1134 } else if (!enteringCheat && (event.key.keysym.sym == SDLK_SPACE ||
1135 event.key.keysym.sym == SDLK_KP3)) {
1136 doFGPlayerAction((Uint32)spritex, (Uint32)spritey);
1137 #ifdef ALLOW_CHEATCODES
1138 } else if (!enteringCheat && event.key.keysym.sym == SDLK_q) {
1139 if(guiYesNoDialog("End the running game?", "Are you sure?", false)) {
1140 gamedata.player->lives = 0;
1141 gameRunning = false;;
1142 }
1143 } else if (!enteringCheat && event.key.keysym.sym == SDLK_p) {
1144 isPauseMode = !isPauseMode;
1145 } else if (event.key.keysym.sym == SDLK_TAB && !isPauseMode) {
1146 enteringCheat = !enteringCheat;
1147 cheatCode[0] = 0;
1148 } else if (enteringCheat == true && event.key.keysym.sym == SDLK_RETURN) {
1149 if(strcmp(cheatCode, "nuke") == 0) {
1150 printf("Nuking all monsters and adding them to your score...\n");
1151 MONSTERS* monster = lhandle.monsters;
1152 while(monster) {
1153 if(monster->isAlive) {
1154 gamedata.player->score += monster->score;
1155 monster->isAlive = false;
1156 monster->isDying = true;
1157 }
1158 monster = monster->next;
1159 }
1160 gamedata.bphuc = true;
1161 } else if(strcmp(cheatCode, "skip") == 0) {
1162 gameRunning = false;
1163 gamedata.bphuc = true;
1164 gamedata.player->score = 0;
1165 showLoading();
1166 } else if(strncmp(cheatCode, "goto ", 5) == 0) {
1167 Uint32 lnum = (Uint32)atoi(((char*)cheatCode)+sizeof("goto"));
1168 if(lnum > 0) {
1169 gamedata.player->level = lnum - 1;
1170 lhandle.nextlevels[0] = lnum;
1171 gameRunning = false;
1172 }
1173 gamedata.bphuc = true;
1174 gamedata.player->score = 0;
1175 showLoading();
1176 } else if(strcmp(cheatCode, "lives") == 0) {
1177 gamedata.player->lives = 99;
1178 gamedata.bphuc = true;
1179 } else if(strcmp(cheatCode, "die") == 0) {
1180 gamedata.player->lives = 0;
1181 gameRunning = false;
1182 showLoading();
1183 } else if(strcmp(cheatCode, "quit") == 0) {
1184 printf("Trying fast exit....\n");
1185 displaymessage(displaymessage_INFO, "Exit using cheat code", 1000);
1186 exit(0);
1187 } else if(strcmp(cheatCode, "coords") == 0) {
1188 displayPlayerCoords = !displayPlayerCoords;
1189 } else if(strcmp(cheatCode, "freemode") == 0) {
1190 freeMovement = !freeMovement;
1191 gamedata.bphuc = true;
1192 } else if(strcmp(cheatCode, "godmode") == 0) {
1193 isGodMode = !isGodMode;
1194 gamedata.bphuc = true;
1195 } else if(strcmp(cheatCode, "timebonus") == 0) {
1196 if (gamedata.player->score > 5000) {
1197 gamedata.player->score -= 5000;
1198 } else {
1199 gamedata.player->score = 0;
1200 }
1201 lhandle.remaintime = lhandle.remaintime + 50;
1202 gamedata.bphuc = true;
1203 } else if(strcmp(cheatCode, "edit") == 0) {
1204 gamedata.player->score = 0;
1205 isEditMode = !isEditMode;
1206 freeMovement = isEditMode;
1207 isGodMode = isEditMode;
1208 displayPlayerCoords = isEditMode;
1209 soundPlayFX(FX_KILL_PLAYER);
1210 showPicture("livelost.jpg", 200);
1211 gLastTick = BS_GetTicks();
1212 gamedata.bphuc = true;
1213 if (isEditMode) {
1214 gamedata.player->lives = 999;
1215 }
1216 }
1217 cheatCode[0] = 0;
1218 enteringCheat = false;
1219 } else if(enteringCheat) {
1220 /* Cheatcode may only contain the characters in CHEATCODECHARS */
1221 if(strchr(CHEATCODECHARS, event.key.keysym.sym) && strlen(cheatCode) < 30) {
1222 sprintf(cheatCode, "%s%c", cheatCode,event.key.keysym.sym);
1223 } ;
1224 if ((event.key.keysym.sym == SDLK_BACKSPACE) && (strlen(cheatCode)>0)) { /* Backspace - delete last char */
1225 cheatCode[strlen(cheatCode)-1] = '\0' ;
1226 } ;
1227 cheatTick = BS_GetTicks() + CHEATTIMEOUT;
1228 #endif // ALLOW_CHEATCODES
1229 }
1230
1231
1232 break;
1233 case SDL_QUIT:
1234 exit(0);
1235 }
1236 }
1237
1238 if(turboKeyPressed || (joymove & JOYSTICK_TURBO)) {
1239 turboMode = true;
1240 } else {
1241 turboMode = false;
1242 }
1243 }
1244
1245 if(lhandle.leveltime > 0 && gamedata.player->lives > 0) {
1246 addTimeToScore(); // Visibly add remaining time to score
1247 }
1248 }
1249
1250
addTimeToScore()1251 void addTimeToScore() {
1252 char tmp1[100];
1253 SDL_Event event;
1254 SDL_Color BONUSCOLOR_ACTIVE = { 0xff, 0xff, 0xff, 0 };
1255 Uint32 wtick = BS_GetTicks() + 50;
1256 bool beep = true;
1257
1258 if(enableColor3D) {
1259 BS_Set3DMode(COLOR3D_NONE);
1260 }
1261
1262 while(lhandle.remaintime > 0) {
1263 lhandle.remaintime--;
1264 gamedata.player->score += lhandle.timebonusmultiplicator;
1265 sprintf(tmp1, "Remaining time: %d\n\nScore: %d\n\nPress space to continue immediately.", (Uint32)lhandle.remaintime, gamedata.player->score);
1266
1267 drawrect(0, 0, SCR_WIDTH, SCR_HEIGHT, 0x00000000);
1268 renderFontHandlerText(0, 50, "SCORE", BONUSCOLOR_ACTIVE, true, false, FONT_menufont_50);
1269 renderFontHandlerText(50, 200, tmp1, BONUSCOLOR_ACTIVE, false, false, FONT_menufont_20);
1270 BS_Flip(gScreen);
1271 if(beep) {
1272 soundPlayFX(FX_COLLECT_PIXEL);
1273 }
1274 beep = !beep;
1275 while(wtick > BS_GetTicks()) {
1276 SDL_Delay(1);
1277 }
1278 wtick = BS_GetTicks() + 50;
1279 // Handle Keyboard
1280 SDL_PollEvent(&event) ;
1281 if(event.type == SDL_KEYUP) {
1282 #ifdef ALLOW_BOSSKEY
1283 if (event.key.keysym.sym == SDLK_ESCAPE) {
1284 displaymessage(displaymessage_INFO, "Boss-key (ESC) hit - fast exit", 800);
1285 exit(0);
1286 }
1287 #endif // ALLOW_BOSSKEY
1288 if (event.key.keysym.sym == SDLK_SPACE) {
1289 /* Add score and continue game immediately */
1290 gamedata.player->score += lhandle.timebonusmultiplicator * ((Uint32)lhandle.remaintime) ;
1291 lhandle.remaintime = 0 ;
1292 }
1293 }
1294 }
1295 SDL_Delay(1000);
1296 }
1297
BS_GetTicks()1298 Uint32 BS_GetTicks() {
1299 if(!isPauseMode) {
1300 BS_MyTick += (SDL_GetTicks() - BS_MyLastTick);
1301 }
1302 BS_MyLastTick = SDL_GetTicks();
1303 return BS_MyTick;
1304 }
1305